diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 12:41:41 +0000 |
commit | 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch) | |
tree | bdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/git2/src/string_array.rs | |
parent | Releasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff) | |
download | rustc-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.rs | 133 |
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) } + } +} |