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