non_empty_str/
iter.rs

1//! Various iterators over non-empty strings.
2
3use core::{iter::Map, str};
4
5use non_empty_iter::NonEmptyIterator;
6
7use crate::{internal::Byte, str::NonEmptyStr};
8
9/// Represents functions mapping non-empty [`prim@str`] to [`NonEmptyStr`].
10///
11/// This is mostly an implementation detail, though it can be useful in case
12/// one needs to name the type of the iterator explicitly.
13pub type NonEmptyStrFn<'s> = fn(&'s str) -> &'s NonEmptyStr;
14
15/// Represents non-empty iterators over the bytes in non-empty strings.
16///
17/// This `struct` is created by the [`bytes`] method on [`NonEmptyStr`].
18///
19/// [`bytes`]: NonEmptyStr::bytes
20#[derive(Debug)]
21pub struct Bytes<'s> {
22    string: &'s NonEmptyStr,
23}
24
25impl<'s> Bytes<'s> {
26    /// Constructs [`Self`].
27    #[must_use]
28    pub const fn new(string: &'s NonEmptyStr) -> Self {
29        Self { string }
30    }
31}
32
33impl<'s> IntoIterator for Bytes<'s> {
34    type Item = Byte;
35    type IntoIter = str::Bytes<'s>;
36
37    fn into_iter(self) -> Self::IntoIter {
38        self.string.as_str().bytes()
39    }
40}
41
42unsafe impl NonEmptyIterator for Bytes<'_> {}
43
44/// Represents non-empty iterators over the characters in non-empty strings.
45///
46/// This `struct` is created by the [`chars`] method on [`NonEmptyStr`].
47///
48/// [`chars`]: NonEmptyStr::chars
49#[derive(Debug)]
50pub struct Chars<'s> {
51    string: &'s NonEmptyStr,
52}
53
54impl<'s> Chars<'s> {
55    /// Constructs [`Self`].
56    #[must_use]
57    pub const fn new(string: &'s NonEmptyStr) -> Self {
58        Self { string }
59    }
60}
61
62impl<'s> IntoIterator for Chars<'s> {
63    type Item = char;
64    type IntoIter = str::Chars<'s>;
65
66    fn into_iter(self) -> Self::IntoIter {
67        self.string.as_str().chars()
68    }
69}
70
71unsafe impl NonEmptyIterator for Chars<'_> {}
72
73/// Represents non-empty iterators over the characters and their positions in non-empty strings.
74///
75/// This `struct` is created by the [`char_indices`] method on [`NonEmptyStr`].
76///
77/// [`char_indices`]: NonEmptyStr::char_indices
78#[derive(Debug)]
79pub struct CharIndices<'s> {
80    string: &'s NonEmptyStr,
81}
82
83impl<'s> CharIndices<'s> {
84    /// Constructs [`Self`].
85    #[must_use]
86    pub const fn new(string: &'s NonEmptyStr) -> Self {
87        Self { string }
88    }
89}
90
91impl<'s> IntoIterator for CharIndices<'s> {
92    type Item = (usize, char);
93    type IntoIter = str::CharIndices<'s>;
94
95    fn into_iter(self) -> Self::IntoIter {
96        self.string.as_str().char_indices()
97    }
98}
99
100unsafe impl NonEmptyIterator for CharIndices<'_> {}
101
102/// Represents iterators over the non-whitespace non-empty substrings of non-empty strings.
103///
104/// Note that this `struct` does not implement [`NonEmptyIterator`] as the iterator can be empty,
105/// specifically, if the input string consists of whitespace only.
106///
107/// This `struct` is created by the [`split_whitespace`] method on [`NonEmptyStr`].
108///
109/// [`split_whitespace`]: NonEmptyStr::split_whitespace
110#[derive(Debug)]
111pub struct SplitWhitespace<'s> {
112    string: &'s NonEmptyStr,
113}
114
115impl<'s> SplitWhitespace<'s> {
116    /// Constructs [`Self`].
117    #[must_use]
118    pub const fn new(string: &'s NonEmptyStr) -> Self {
119        Self { string }
120    }
121}
122
123impl<'s> IntoIterator for SplitWhitespace<'s> {
124    type Item = &'s NonEmptyStr;
125    type IntoIter = Map<str::SplitWhitespace<'s>, NonEmptyStrFn<'s>>;
126
127    fn into_iter(self) -> Self::IntoIter {
128        self.string
129            .as_str()
130            .split_whitespace()
131            // SAFETY: `split_whitespace` never yields empty substrings
132            .map(|string| unsafe { NonEmptyStr::from_str_unchecked(string) })
133    }
134}
135
136// NOTE: `SplitWhitespace<'_>` does not implement `NonEmptyIterator` as it can be empty,
137// specifically, if the input string consists of whitespace only
138
139/// Represents iterators over the non-ASCII-whitespace non-empty substrings of non-empty strings.
140///
141/// Note that this `struct` does not implement [`NonEmptyIterator`] as the iterator can be empty,
142/// specifically, if the input string consists of ASCII whitespace only.
143///
144/// This `struct` is created by the [`split_ascii_whitespace`] method on [`NonEmptyStr`].
145///
146/// [`split_ascii_whitespace`]: NonEmptyStr::split_ascii_whitespace
147#[derive(Debug)]
148pub struct SplitAsciiWhitespace<'s> {
149    string: &'s NonEmptyStr,
150}
151
152impl<'s> SplitAsciiWhitespace<'s> {
153    /// Constructs [`Self`].
154    #[must_use]
155    pub const fn new(string: &'s NonEmptyStr) -> Self {
156        Self { string }
157    }
158}
159
160impl<'s> IntoIterator for SplitAsciiWhitespace<'s> {
161    type Item = &'s NonEmptyStr;
162    type IntoIter = Map<str::SplitAsciiWhitespace<'s>, NonEmptyStrFn<'s>>;
163
164    fn into_iter(self) -> Self::IntoIter {
165        self.string
166            .as_str()
167            .split_ascii_whitespace()
168            // SAFETY: `split_ascii_whitespace` never yields empty substrings
169            .map(|string| unsafe { NonEmptyStr::from_str_unchecked(string) })
170    }
171}
172
173// NOTE: `SplitAsciiWhitespace<'_>` does not implement `NonEmptyIterator` as it can be empty,
174// specifically, if the input string consists of ASCII whitespace only
175
176/// Represents non-empty iterators over the UTF-16 encoding of non-empty strings.
177///
178/// This `struct` is created by the [`encode_utf16`] method on [`NonEmptyStr`].
179///
180/// [`encode_utf16`]: NonEmptyStr::encode_utf16
181#[derive(Debug)]
182pub struct EncodeUtf16<'s> {
183    string: &'s NonEmptyStr,
184}
185
186impl<'s> EncodeUtf16<'s> {
187    /// Constructs [`Self`].
188    #[must_use]
189    pub const fn new(string: &'s NonEmptyStr) -> Self {
190        Self { string }
191    }
192}
193
194impl<'s> IntoIterator for EncodeUtf16<'s> {
195    type Item = u16;
196    type IntoIter = str::EncodeUtf16<'s>;
197
198    fn into_iter(self) -> Self::IntoIter {
199        self.string.as_str().encode_utf16()
200    }
201}
202
203unsafe impl NonEmptyIterator for EncodeUtf16<'_> {}
204
205/// Represents non-empty iterators over the debug-escaped characters in non-empty strings.
206///
207/// This `struct` is created by the [`escape_debug`] method on [`NonEmptyStr`].
208///
209/// [`escape_debug`]: NonEmptyStr::escape_debug
210#[derive(Debug)]
211pub struct EscapeDebug<'s> {
212    string: &'s NonEmptyStr,
213}
214
215impl<'s> EscapeDebug<'s> {
216    /// Constructs [`Self`].
217    #[must_use]
218    pub const fn new(string: &'s NonEmptyStr) -> Self {
219        Self { string }
220    }
221}
222
223impl<'s> IntoIterator for EscapeDebug<'s> {
224    type Item = char;
225    type IntoIter = str::EscapeDebug<'s>;
226
227    fn into_iter(self) -> Self::IntoIter {
228        self.string.as_str().escape_debug()
229    }
230}
231
232unsafe impl NonEmptyIterator for EscapeDebug<'_> {}
233
234/// Represents non-empty iterators over the default-escaped characters in non-empty strings.
235///
236/// This `struct` is created by the [`escape_default`] method on [`NonEmptyStr`].
237///
238/// [`escape_default`]: NonEmptyStr::escape_default
239#[derive(Debug)]
240pub struct EscapeDefault<'s> {
241    string: &'s NonEmptyStr,
242}
243
244impl<'s> EscapeDefault<'s> {
245    /// Constructs [`Self`].
246    #[must_use]
247    pub const fn new(string: &'s NonEmptyStr) -> Self {
248        Self { string }
249    }
250}
251
252impl<'s> IntoIterator for EscapeDefault<'s> {
253    type Item = char;
254    type IntoIter = str::EscapeDefault<'s>;
255
256    fn into_iter(self) -> Self::IntoIter {
257        self.string.as_str().escape_default()
258    }
259}
260
261unsafe impl NonEmptyIterator for EscapeDefault<'_> {}
262
263/// Represents non-empty iterators over the Unicode-escaped characters in non-empty strings.
264///
265/// This `struct` is created by the [`escape_unicode`] method on [`NonEmptyStr`].
266///
267/// [`escape_unicode`]: NonEmptyStr::escape_unicode
268#[derive(Debug)]
269pub struct EscapeUnicode<'s> {
270    string: &'s NonEmptyStr,
271}
272
273impl<'s> EscapeUnicode<'s> {
274    /// Constructs [`Self`].
275    #[must_use]
276    pub const fn new(string: &'s NonEmptyStr) -> Self {
277        Self { string }
278    }
279}
280
281impl<'s> IntoIterator for EscapeUnicode<'s> {
282    type Item = char;
283    type IntoIter = str::EscapeUnicode<'s>;
284
285    fn into_iter(self) -> Self::IntoIter {
286        self.string.as_str().escape_unicode()
287    }
288}
289
290unsafe impl NonEmptyIterator for EscapeUnicode<'_> {}
291
292/// Represents non-empty iterators over the lines in non-empty strings.
293///
294/// This `struct` is created by the [`lines`] method on [`NonEmptyStr`].
295///
296/// [`lines`]: NonEmptyStr::lines
297#[derive(Debug)]
298pub struct Lines<'s> {
299    string: &'s NonEmptyStr,
300}
301
302impl<'s> Lines<'s> {
303    /// Constructs [`Self`].
304    #[must_use]
305    pub const fn new(string: &'s NonEmptyStr) -> Self {
306        Self { string }
307    }
308}
309
310impl<'s> IntoIterator for Lines<'s> {
311    type Item = &'s str;
312
313    type IntoIter = str::Lines<'s>;
314
315    fn into_iter(self) -> Self::IntoIter {
316        self.string.as_str().lines()
317    }
318}
319
320unsafe impl NonEmptyIterator for Lines<'_> {}