string_iter/
iterators.rs

1
2use core::ops::{Deref, DerefMut};
3use core::iter::FusedIterator;
4use crate::StringIter;
5
6
7impl<'t> Iterator for StringIter<'t> {
8    type Item = (char, &'t str);
9
10    #[inline]
11    fn next(&mut self) -> Option<Self::Item> {
12        self.next_char()
13    }
14
15    fn size_hint(&self) -> (usize, Option<usize>) {
16        (self.str.len(), Some(self.str.len()))
17    }
18
19    fn count(self) -> usize {
20        self.str.chars().count()
21    }
22}
23
24impl<'t> DoubleEndedIterator for StringIter<'t> {
25    
26    #[inline]
27    fn next_back(&mut self) -> Option<Self::Item> {
28        self.next_char_back()
29    }
30}
31
32impl<'t> FusedIterator for StringIter<'t> {}
33
34impl<'t> StringIter<'t> {
35    
36    /// Map the iterator into an `Iterator<Item = char>`.
37    /// 
38    /// Discarding the str output
39    pub fn chars(self) -> CharIter<'t>{
40        CharIter(self)
41    }
42
43    /// Map the iterator into an `Iterator<Item = &str>`.
44    /// 
45    /// Discarding the char output
46    pub fn strs(self) -> StrIter<'t>{
47        StrIter(self)
48    }
49
50    /// Map the iterator into an `Iterator<Item = u8>`.
51    /// 
52    /// where u8 is the first byte of the &str.
53    pub fn ascii(self) -> AsciiIter<'t> {
54        AsciiIter(self)
55    }
56
57    /// Map the iterator into an `Iterator<Item = (u8, &str)>`.
58    /// 
59    /// where u8 is the first byte of the &str.
60    pub fn ascii_str(self) -> AsciiStrIter<'t> {
61        AsciiStrIter(self)
62    }
63
64    /// Make the iterator peek for `len`.
65    pub fn look_ahead(self, len: usize) -> LookAhead<'t> {
66        assert!(len != 0, "look_ahead cannot be 0");
67        LookAhead { iter: self, look_ahead: len }
68    }
69}
70
71macro_rules! alt_iter {
72    ($name: ident, $base:ident, $item: ty, $func: expr, $doc: literal) => {
73
74        #[doc = $doc]
75        #[repr(transparent)]
76        #[derive(Debug, Clone)]
77        pub struct $name<'t>($base<'t>);
78
79        impl<'t> Deref for $name<'t> {
80            type Target = $base<'t>;
81
82            fn deref(&self) -> &Self::Target {
83                &self.0
84            }
85        }
86
87        impl<'t> DerefMut for $name<'t> {
88            fn deref_mut(&mut self) -> &mut Self::Target {
89                &mut self.0
90            }
91        }
92
93        impl core::borrow::Borrow<str> for $name<'_> {
94            fn borrow(&self) -> &str {
95                self.0.as_str()
96            }
97        }
98
99        impl AsRef<str> for $name<'_> {
100            fn as_ref(&self) -> &str {
101                self.0.as_str()
102            }
103        }
104
105        impl<'t> Iterator for $name<'t> {
106            type Item = $item;
107
108            #[inline]
109            fn next(&mut self) -> Option<Self::Item> {
110                self.0.next().map($func)
111            }
112
113
114            fn size_hint(&self) -> (usize, Option<usize>) {
115                self.0.size_hint()
116            }
117
118            fn count(self) -> usize {
119                self.0.count()
120            }
121        }
122
123        impl<'t> DoubleEndedIterator for $name<'t> {
124            #[inline]
125            fn next_back(&mut self) -> Option<Self::Item> {
126                self.0.next_back().map($func)
127            }
128        }
129
130        impl<'t> FusedIterator for $name<'t> {}
131    };
132}
133
134alt_iter!(CharIter, StringIter, char, |(c, _)| c,
135    "A mapped [`StringIter`] that yields [`char`]s.");
136alt_iter!(StrIter, StringIter, &'t str, |(_, s)| s,
137    "A mapped [`StringIter`] that yields [`&str`]s.");
138alt_iter!(AsciiIter, StringIter, u8, |(_, s)| unsafe {*s.as_bytes().get_unchecked(0)},
139    "A mapped [`StringIter`] that yields [`u8`]s.");
140alt_iter!(AsciiStrIter, StringIter, (u8, &'t str), |(_, s)| (unsafe {*s.as_bytes().get_unchecked(0)}, s),
141    "A mapped [`StringIter`] that yields `(u8, &str)`s.");
142
143
144/// A mapped StringIter that yields longer [`&str`]s by looking ahead.
145#[derive(Debug, Clone)]
146pub struct LookAhead<'t>{
147    iter: StringIter<'t>,
148    look_ahead: usize,
149}
150
151impl<'t> Deref for LookAhead<'t> {
152    type Target = StringIter<'t>;
153
154    fn deref(&self) -> &Self::Target {
155        &self.iter
156    }
157}
158
159impl<'t> DerefMut for LookAhead<'t> {
160    fn deref_mut(&mut self) -> &mut Self::Target {
161        &mut self.iter
162    }
163}
164
165impl<'t> Iterator for LookAhead<'t> {
166    type Item = (char, &'t str);
167
168    #[inline]
169    fn next(&mut self) -> Option<Self::Item> {
170        let s = match self.iter.peekn(self.look_ahead) {
171            Ok(s) => s,
172            Err(s) => s,
173        };
174        self.iter.next().map(|(c, _)| (c, s))
175    }
176
177
178    fn size_hint(&self) -> (usize, Option<usize>) {
179        self.iter.size_hint()
180    }
181
182    fn count(self) -> usize {
183        self.iter.count()
184    }
185}
186
187impl<'t> DoubleEndedIterator for LookAhead<'t> {
188    #[inline]
189    fn next_back(&mut self) -> Option<Self::Item> {
190        let s = match self.iter.peekn_back(self.look_ahead) {
191            Ok(s) => s,
192            Err(s) => s,
193        };
194        self.iter.next().map(|(c, _)| (c, s))
195    }
196}
197
198impl<'t> FusedIterator for LookAhead<'t> {}
199
200impl<'t> LookAhead<'t> {
201
202    /// Map the iterator into an `Iterator<Item = &str>`.
203    pub fn strs(self) -> LookAheadStrIter<'t>{
204        LookAheadStrIter(self)
205    }
206}
207
208alt_iter!(LookAheadStrIter, LookAhead, &'t str, |(_, s)| s,
209    "A mapped [`LookAhead`] that yields [`&str`]s.");