summaryrefslogtreecommitdiffstats
path: root/vendor/git2/src/string_array.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/git2/src/string_array.rs
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/git2/src/string_array.rs')
-rw-r--r--vendor/git2/src/string_array.rs133
1 files changed, 133 insertions, 0 deletions
diff --git a/vendor/git2/src/string_array.rs b/vendor/git2/src/string_array.rs
new file mode 100644
index 000000000..1aa6fbb41
--- /dev/null
+++ b/vendor/git2/src/string_array.rs
@@ -0,0 +1,133 @@
+//! Bindings to libgit2's raw `git_strarray` type
+
+use std::ops::Range;
+use std::str;
+
+use crate::raw;
+use crate::util::Binding;
+
+/// A string array structure used by libgit2
+///
+/// Some APIs return arrays of strings which originate from libgit2. This
+/// wrapper type behaves a little like `Vec<&str>` but does so without copying
+/// the underlying strings until necessary.
+pub struct StringArray {
+ raw: raw::git_strarray,
+}
+
+/// A forward iterator over the strings of an array, casted to `&str`.
+pub struct Iter<'a> {
+ range: Range<usize>,
+ arr: &'a StringArray,
+}
+
+/// A forward iterator over the strings of an array, casted to `&[u8]`.
+pub struct IterBytes<'a> {
+ range: Range<usize>,
+ arr: &'a StringArray,
+}
+
+impl StringArray {
+ /// Returns None if the i'th string is not utf8 or if i is out of bounds.
+ pub fn get(&self, i: usize) -> Option<&str> {
+ self.get_bytes(i).and_then(|s| str::from_utf8(s).ok())
+ }
+
+ /// Returns None if `i` is out of bounds.
+ pub fn get_bytes(&self, i: usize) -> Option<&[u8]> {
+ if i < self.raw.count as usize {
+ unsafe {
+ let ptr = *self.raw.strings.add(i) as *const _;
+ Some(crate::opt_bytes(self, ptr).unwrap())
+ }
+ } else {
+ None
+ }
+ }
+
+ /// Returns an iterator over the strings contained within this array.
+ ///
+ /// The iterator yields `Option<&str>` as it is unknown whether the contents
+ /// are utf-8 or not.
+ pub fn iter(&self) -> Iter<'_> {
+ Iter {
+ range: 0..self.len(),
+ arr: self,
+ }
+ }
+
+ /// Returns an iterator over the strings contained within this array,
+ /// yielding byte slices.
+ pub fn iter_bytes(&self) -> IterBytes<'_> {
+ IterBytes {
+ range: 0..self.len(),
+ arr: self,
+ }
+ }
+
+ /// Returns the number of strings in this array.
+ pub fn len(&self) -> usize {
+ self.raw.count as usize
+ }
+
+ /// Return `true` if this array is empty.
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+}
+
+impl Binding for StringArray {
+ type Raw = raw::git_strarray;
+ unsafe fn from_raw(raw: raw::git_strarray) -> StringArray {
+ StringArray { raw }
+ }
+ fn raw(&self) -> raw::git_strarray {
+ self.raw
+ }
+}
+
+impl<'a> IntoIterator for &'a StringArray {
+ type Item = Option<&'a str>;
+ type IntoIter = Iter<'a>;
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
+
+impl<'a> Iterator for Iter<'a> {
+ type Item = Option<&'a str>;
+ fn next(&mut self) -> Option<Option<&'a str>> {
+ self.range.next().map(|i| self.arr.get(i))
+ }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.range.size_hint()
+ }
+}
+impl<'a> DoubleEndedIterator for Iter<'a> {
+ fn next_back(&mut self) -> Option<Option<&'a str>> {
+ self.range.next_back().map(|i| self.arr.get(i))
+ }
+}
+impl<'a> ExactSizeIterator for Iter<'a> {}
+
+impl<'a> Iterator for IterBytes<'a> {
+ type Item = &'a [u8];
+ fn next(&mut self) -> Option<&'a [u8]> {
+ self.range.next().and_then(|i| self.arr.get_bytes(i))
+ }
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.range.size_hint()
+ }
+}
+impl<'a> DoubleEndedIterator for IterBytes<'a> {
+ fn next_back(&mut self) -> Option<&'a [u8]> {
+ self.range.next_back().and_then(|i| self.arr.get_bytes(i))
+ }
+}
+impl<'a> ExactSizeIterator for IterBytes<'a> {}
+
+impl Drop for StringArray {
+ fn drop(&mut self) {
+ unsafe { raw::git_strarray_free(&mut self.raw) }
+ }
+}