1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::str;
use std::ops::Range;
use raw;
use util::Binding;
pub struct StringArray {
raw: raw::git_strarray,
}
pub struct Iter<'a> {
range: Range<usize>,
arr: &'a StringArray,
}
pub struct IterBytes<'a> {
range: Range<usize>,
arr: &'a StringArray,
}
impl StringArray {
pub fn get(&self, i: usize) -> Option<&str> {
self.get_bytes(i).and_then(|s| str::from_utf8(s).ok())
}
pub fn get_bytes(&self, i: usize) -> Option<&[u8]> {
if i < self.raw.count as usize {
unsafe {
let ptr = *self.raw.strings.offset(i as isize) as *const _;
Some(::opt_bytes(self, ptr).unwrap())
}
} else {
None
}
}
pub fn iter(&self) -> Iter {
Iter { range: 0..self.len(), arr: self }
}
pub fn iter_bytes(&self) -> IterBytes {
IterBytes { range: 0..self.len(), arr: self }
}
pub fn len(&self) -> usize { self.raw.count as usize }
}
impl Binding for StringArray {
type Raw = raw::git_strarray;
unsafe fn from_raw(raw: raw::git_strarray) -> StringArray {
StringArray { raw: raw }
}
fn raw(&self) -> raw::git_strarray { self.raw }
}
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) }
}
}