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 pub fn chars(self) -> CharIter<'t>{
40 CharIter(self)
41 }
42
43 pub fn strs(self) -> StrIter<'t>{
47 StrIter(self)
48 }
49
50 pub fn ascii(self) -> AsciiIter<'t> {
54 AsciiIter(self)
55 }
56
57 pub fn ascii_str(self) -> AsciiStrIter<'t> {
61 AsciiStrIter(self)
62 }
63
64 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#[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 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.");