1 use {memchr, memchr2, memchr3, memrchr, memrchr2, memrchr3};
2 
3 macro_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 
23 macro_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`.
34 pub struct Memchr<'a> {
35     needle: u8,
36     // The haystack to iterate over
37     haystack: &'a [u8],
38     // The index
39     position: usize,
40 }
41 
42 impl<'a> Memchr<'a> {
43     /// Creates a new iterator that yields all positions of needle in haystack.
44     #[inline]
new(needle: u8, haystack: &[u8]) -> Memchr45     pub fn new(needle: u8, haystack: &[u8]) -> Memchr {
46         Memchr { needle: needle, haystack: haystack, position: 0 }
47     }
48 }
49 
50 impl<'a> Iterator for Memchr<'a> {
51     type Item = usize;
52 
53     #[inline]
next(&mut self) -> Option<usize>54     fn next(&mut self) -> Option<usize> {
55         iter_next!(self, memchr(self.needle, self.haystack))
56     }
57 
58     #[inline]
size_hint(&self) -> (usize, Option<usize>)59     fn size_hint(&self) -> (usize, Option<usize>) {
60         (0, Some(self.haystack.len()))
61     }
62 }
63 
64 impl<'a> DoubleEndedIterator for Memchr<'a> {
65     #[inline]
next_back(&mut self) -> Option<Self::Item>66     fn next_back(&mut self) -> Option<Self::Item> {
67         iter_next_back!(self, memrchr(self.needle, self.haystack))
68     }
69 }
70 
71 /// An iterator for `memchr2`.
72 pub struct Memchr2<'a> {
73     needle1: u8,
74     needle2: u8,
75     // The haystack to iterate over
76     haystack: &'a [u8],
77     // The index
78     position: usize,
79 }
80 
81 impl<'a> Memchr2<'a> {
82     /// Creates a new iterator that yields all positions of needle in haystack.
83     #[inline]
new(needle1: u8, needle2: u8, haystack: &[u8]) -> Memchr284     pub fn new(needle1: u8, needle2: u8, haystack: &[u8]) -> Memchr2 {
85         Memchr2 {
86             needle1: needle1,
87             needle2: needle2,
88             haystack: haystack,
89             position: 0,
90         }
91     }
92 }
93 
94 impl<'a> Iterator for Memchr2<'a> {
95     type Item = usize;
96 
97     #[inline]
next(&mut self) -> Option<usize>98     fn next(&mut self) -> Option<usize> {
99         iter_next!(self, memchr2(self.needle1, self.needle2, self.haystack))
100     }
101 
102     #[inline]
size_hint(&self) -> (usize, Option<usize>)103     fn size_hint(&self) -> (usize, Option<usize>) {
104         (0, Some(self.haystack.len()))
105     }
106 }
107 
108 impl<'a> DoubleEndedIterator for Memchr2<'a> {
109     #[inline]
next_back(&mut self) -> Option<Self::Item>110     fn next_back(&mut self) -> Option<Self::Item> {
111         iter_next_back!(
112             self,
113             memrchr2(self.needle1, self.needle2, self.haystack)
114         )
115     }
116 }
117 
118 /// An iterator for `memchr3`.
119 pub struct Memchr3<'a> {
120     needle1: u8,
121     needle2: u8,
122     needle3: u8,
123     // The haystack to iterate over
124     haystack: &'a [u8],
125     // The index
126     position: usize,
127 }
128 
129 impl<'a> Memchr3<'a> {
130     /// Create a new `Memchr3` that's initialized to zero with a haystack
131     #[inline]
new( needle1: u8, needle2: u8, needle3: u8, haystack: &[u8], ) -> Memchr3132     pub fn new(
133         needle1: u8,
134         needle2: u8,
135         needle3: u8,
136         haystack: &[u8],
137     ) -> Memchr3 {
138         Memchr3 {
139             needle1: needle1,
140             needle2: needle2,
141             needle3: needle3,
142             haystack: haystack,
143             position: 0,
144         }
145     }
146 }
147 
148 impl<'a> Iterator for Memchr3<'a> {
149     type Item = usize;
150 
151     #[inline]
next(&mut self) -> Option<usize>152     fn next(&mut self) -> Option<usize> {
153         iter_next!(
154             self,
155             memchr3(self.needle1, self.needle2, self.needle3, self.haystack)
156         )
157     }
158 
159     #[inline]
size_hint(&self) -> (usize, Option<usize>)160     fn size_hint(&self) -> (usize, Option<usize>) {
161         (0, Some(self.haystack.len()))
162     }
163 }
164 
165 impl<'a> DoubleEndedIterator for Memchr3<'a> {
166     #[inline]
next_back(&mut self) -> Option<Self::Item>167     fn next_back(&mut self) -> Option<Self::Item> {
168         iter_next_back!(
169             self,
170             memrchr3(self.needle1, self.needle2, self.needle3, self.haystack)
171         )
172     }
173 }
174