1use crate::{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 { needle: needle, haystack: haystack, position: 0 }
47 }
48}
49
50impl<'a> Iterator for Memchr<'a> {
51 type Item = usize;
52
53 #[inline]
54 fn next(&mut self) -> Option<usize> {
55 iter_next!(self, memchr(self.needle, self.haystack))
56 }
57
58 #[inline]
59 fn size_hint(&self) -> (usize, Option<usize>) {
60 (0, Some(self.haystack.len()))
61 }
62}
63
64impl<'a> DoubleEndedIterator for Memchr<'a> {
65 #[inline]
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`.
72pub 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
81impl<'a> Memchr2<'a> {
82 /// Creates a new iterator that yields all positions of needle in haystack.
83 #[inline]
84 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
94impl<'a> Iterator for Memchr2<'a> {
95 type Item = usize;
96
97 #[inline]
98 fn next(&mut self) -> Option<usize> {
99 iter_next!(self, memchr2(self.needle1, self.needle2, self.haystack))
100 }
101
102 #[inline]
103 fn size_hint(&self) -> (usize, Option<usize>) {
104 (0, Some(self.haystack.len()))
105 }
106}
107
108impl<'a> DoubleEndedIterator for Memchr2<'a> {
109 #[inline]
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`.
119pub 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
129impl<'a> Memchr3<'a> {
130 /// Create a new `Memchr3` that's initialized to zero with a haystack
131 #[inline]
132 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
148impl<'a> Iterator for Memchr3<'a> {
149 type Item = usize;
150
151 #[inline]
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]
160 fn size_hint(&self) -> (usize, Option<usize>) {
161 (0, Some(self.haystack.len()))
162 }
163}
164
165impl<'a> DoubleEndedIterator for Memchr3<'a> {
166 #[inline]
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