memchr/
iter.rs

1use {memchr, memchr2, memchr3, memrchr, memrchr2, memrchr3};
2
3macro_rules! iter_next {
4    // Common code for the memchr iterators:
5    // update haystack and position and produce the index
6    //
7    // self: &mut Self where Self is the iterator
8    // search_result: Option<usize> which is the result of the corresponding
9    // memchr function.
10    //
11    // Returns Option<usize> (the next iterator element)
12    ($self_:expr, $search_result:expr) => {
13        $search_result.map(move |index| {
14            // split and take the remaining back half
15            $self_.haystack = $self_.haystack.split_at(index + 1).1;
16            let found_position = $self_.position + index;
17            $self_.position = found_position + 1;
18            found_position
19        })
20    }
21}
22
23macro_rules! iter_next_back {
24    ($self_:expr, $search_result:expr) => {
25        $search_result.map(move |index| {
26            // split and take the remaining front half
27            $self_.haystack = $self_.haystack.split_at(index).0;
28            $self_.position + index
29        })
30    }
31}
32
33/// An iterator for `memchr`.
34pub struct Memchr<'a> {
35    needle: u8,
36    // The haystack to iterate over
37    haystack: &'a [u8],
38    // The index
39    position: usize,
40}
41
42impl<'a> Memchr<'a> {
43    /// Creates a new iterator that yields all positions of needle in haystack.
44    #[inline]
45    pub fn new(needle: u8, haystack: &[u8]) -> Memchr {
46        Memchr {
47            needle: needle,
48            haystack: haystack,
49            position: 0,
50        }
51    }
52}
53
54impl<'a> Iterator for Memchr<'a> {
55    type Item = usize;
56
57    #[inline]
58    fn next(&mut self) -> Option<usize> {
59        iter_next!(self, memchr(self.needle, self.haystack))
60    }
61
62    #[inline]
63    fn size_hint(&self) -> (usize, Option<usize>) {
64        (0, Some(self.haystack.len()))
65    }
66}
67
68impl<'a> DoubleEndedIterator for Memchr<'a> {
69    #[inline]
70    fn next_back(&mut self) -> Option<Self::Item> {
71        iter_next_back!(self, memrchr(self.needle, self.haystack))
72    }
73}
74
75/// An iterator for `memchr2`.
76pub struct Memchr2<'a> {
77    needle1: u8,
78    needle2: u8,
79    // The haystack to iterate over
80    haystack: &'a [u8],
81    // The index
82    position: usize,
83}
84
85impl<'a> Memchr2<'a> {
86    /// Creates a new iterator that yields all positions of needle in haystack.
87    #[inline]
88    pub fn new(needle1: u8, needle2: u8, haystack: &[u8]) -> Memchr2 {
89        Memchr2 {
90            needle1: needle1,
91            needle2: needle2,
92            haystack: haystack,
93            position: 0,
94        }
95    }
96}
97
98impl<'a> Iterator for Memchr2<'a> {
99    type Item = usize;
100
101    #[inline]
102    fn next(&mut self) -> Option<usize> {
103        iter_next!(self, memchr2(self.needle1, self.needle2, self.haystack))
104    }
105
106    #[inline]
107    fn size_hint(&self) -> (usize, Option<usize>) {
108        (0, Some(self.haystack.len()))
109    }
110}
111
112impl<'a> DoubleEndedIterator for Memchr2<'a> {
113    #[inline]
114    fn next_back(&mut self) -> Option<Self::Item> {
115        iter_next_back!(
116            self,
117            memrchr2(self.needle1, self.needle2, self.haystack)
118        )
119    }
120}
121
122/// An iterator for `memchr3`.
123pub struct Memchr3<'a> {
124    needle1: u8,
125    needle2: u8,
126    needle3: u8,
127    // The haystack to iterate over
128    haystack: &'a [u8],
129    // The index
130    position: usize,
131}
132
133impl<'a> Memchr3<'a> {
134    /// Create a new `Memchr3` that's initialized to zero with a haystack
135    #[inline]
136    pub fn new(
137        needle1: u8,
138        needle2: u8,
139        needle3: u8,
140        haystack: &[u8],
141    ) -> Memchr3 {
142        Memchr3 {
143            needle1: needle1,
144            needle2: needle2,
145            needle3: needle3,
146            haystack: haystack,
147            position: 0,
148        }
149    }
150}
151
152impl<'a> Iterator for Memchr3<'a> {
153    type Item = usize;
154
155    #[inline]
156    fn next(&mut self) -> Option<usize> {
157        iter_next!(
158            self,
159            memchr3(self.needle1, self.needle2, self.needle3, self.haystack)
160        )
161    }
162
163    #[inline]
164    fn size_hint(&self) -> (usize, Option<usize>) {
165        (0, Some(self.haystack.len()))
166    }
167}
168
169impl<'a> DoubleEndedIterator for Memchr3<'a> {
170    #[inline]
171    fn next_back(&mut self) -> Option<Self::Item> {
172        iter_next_back!(
173            self,
174            memrchr3(self.needle1, self.needle2, self.needle3, self.haystack)
175        )
176    }
177}