non_empty_slice/
iter.rs

1//! Various non-empty iterators over non-empty vectors and slices.
2
3#[cfg(feature = "std")]
4use std::vec::IntoIter;
5
6#[cfg(all(not(feature = "std"), feature = "alloc"))]
7use alloc::vec::IntoIter;
8
9use core::{
10    fmt,
11    iter::Map,
12    slice::{self, Iter, IterMut},
13};
14
15use non_zero_size::Size;
16
17use non_empty_iter::{NonEmptyAdapter, NonEmptyIterator};
18
19use crate::slice::{NonEmptyBytes, NonEmptySlice};
20
21/// Represents non-empty by-value iterators.
22#[cfg(any(feature = "std", feature = "alloc"))]
23pub type IntoNonEmptyIter<T> = NonEmptyAdapter<IntoIter<T>>;
24
25/// Represents non-empty by-reference iterators.
26pub type NonEmptyIter<'a, T> = NonEmptyAdapter<Iter<'a, T>>;
27
28/// Represents non-empty by-mutable-reference iterators.
29pub type NonEmptyIterMut<'a, T> = NonEmptyAdapter<IterMut<'a, T>>;
30
31/// Represents functions mapping chunks to non-empty slices.
32///
33/// This is mostly an implementation detail, though it can be useful in case
34/// one needs to name the type of the iterator explicitly.
35pub type NonEmptySliceFn<'a, T> = fn(&'a [T]) -> &'a NonEmptySlice<T>;
36
37/// Represents functions mapping mutable chunks to non-empty mutable slices.
38///
39/// This is mostly an implementation detail, though it can be useful in case
40/// one needs to name the type of the iterator explicitly.
41pub type NonEmptyMutSliceFn<'a, T> = fn(&'a mut [T]) -> &'a mut NonEmptySlice<T>;
42
43/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
44/// starting at the beginning of the non-empty slice.
45///
46/// This `struct` is created by the [`chunks`] method on [`NonEmptySlice<T>`].
47///
48/// [`chunks`]: NonEmptySlice::chunks
49#[derive(Debug)]
50pub struct Chunks<'a, T> {
51    slice: &'a NonEmptySlice<T>,
52    size: Size,
53}
54
55impl<'a, T> Chunks<'a, T> {
56    /// Constructs [`Self`].
57    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
58        Self { slice, size }
59    }
60}
61
62impl<'a, T> IntoIterator for Chunks<'a, T> {
63    type Item = &'a NonEmptySlice<T>;
64
65    type IntoIter = Map<slice::Chunks<'a, T>, NonEmptySliceFn<'a, T>>;
66
67    fn into_iter(self) -> Self::IntoIter {
68        self.slice
69            .as_slice()
70            .chunks(self.size.get())
71            // SAFETY: chunks are never empty
72            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
73    }
74}
75
76unsafe impl<T> NonEmptyIterator for Chunks<'_, T> {}
77
78/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
79/// starting at the beginning of the non-empty slice.
80///
81/// This `struct` is created by the [`chunks_mut`] method on [`NonEmptySlice<T>`].
82///
83/// [`chunks_mut`]: NonEmptySlice::chunks_mut
84#[derive(Debug)]
85pub struct ChunksMut<'a, T> {
86    slice: &'a mut NonEmptySlice<T>,
87    size: Size,
88}
89
90impl<'a, T> ChunksMut<'a, T> {
91    /// Constructs [`Self`].
92    pub const fn new(slice: &'a mut NonEmptySlice<T>, size: Size) -> Self {
93        Self { slice, size }
94    }
95}
96
97impl<'a, T> IntoIterator for ChunksMut<'a, T> {
98    type Item = &'a mut NonEmptySlice<T>;
99
100    type IntoIter = Map<slice::ChunksMut<'a, T>, NonEmptyMutSliceFn<'a, T>>;
101
102    fn into_iter(self) -> Self::IntoIter {
103        self.slice
104            .as_mut_slice()
105            .chunks_mut(self.size.get())
106            // SAFETY: chunks are never empty
107            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
108    }
109}
110
111unsafe impl<T> NonEmptyIterator for ChunksMut<'_, T> {}
112
113/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
114/// starting at the end of the non-empty slice.
115///
116/// This `struct` is created by the [`rchunks`] method on [`NonEmptySlice<T>`].
117///
118/// [`rchunks`]: NonEmptySlice::rchunks
119#[derive(Debug)]
120pub struct RChunks<'a, T> {
121    slice: &'a NonEmptySlice<T>,
122    size: Size,
123}
124
125impl<'a, T> RChunks<'a, T> {
126    /// Constructs [`Self`].
127    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
128        Self { slice, size }
129    }
130}
131
132unsafe impl<T> NonEmptyIterator for RChunks<'_, T> {}
133
134impl<'a, T> IntoIterator for RChunks<'a, T> {
135    type Item = &'a NonEmptySlice<T>;
136
137    type IntoIter = Map<slice::RChunks<'a, T>, NonEmptySliceFn<'a, T>>;
138
139    fn into_iter(self) -> Self::IntoIter {
140        self.slice
141            .as_slice()
142            .rchunks(self.size.get())
143            // SAFETY: chunks are never empty
144            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
145    }
146}
147
148/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
149/// starting at the end of the non-empty slice.
150///
151/// This `struct` is created by the [`rchunks_mut`] method on [`NonEmptySlice<T>`].
152///
153/// [`rchunks_mut`]: NonEmptySlice::rchunks_mut
154#[derive(Debug)]
155pub struct RChunksMut<'a, T> {
156    slice: &'a mut NonEmptySlice<T>,
157    size: Size,
158}
159
160impl<'a, T> RChunksMut<'a, T> {
161    /// Constructs [`Self`].
162    pub const fn new(slice: &'a mut NonEmptySlice<T>, size: Size) -> Self {
163        Self { slice, size }
164    }
165}
166
167impl<'a, T> IntoIterator for RChunksMut<'a, T> {
168    type Item = &'a mut NonEmptySlice<T>;
169
170    type IntoIter = Map<slice::RChunksMut<'a, T>, NonEmptyMutSliceFn<'a, T>>;
171
172    fn into_iter(self) -> Self::IntoIter {
173        self.slice
174            .as_mut_slice()
175            .rchunks_mut(self.size.get())
176            // SAFETY: chunks are never empty
177            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
178    }
179}
180
181unsafe impl<T> NonEmptyIterator for RChunksMut<'_, T> {}
182
183/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
184/// starting at the beginning of the non-empty slice.
185///
186/// When the length of the non-empty slice is not divisible by the chunk size,
187/// the last chunk will be omitted.
188///
189/// This `struct` is created by the [`chunks_exact`] method on [`NonEmptySlice<T>`].
190///
191/// [`chunks_exact`]: NonEmptySlice::chunks_exact
192#[derive(Debug)]
193pub struct ChunksExact<'a, T> {
194    slice: &'a NonEmptySlice<T>,
195    size: Size,
196}
197
198impl<'a, T> ChunksExact<'a, T> {
199    /// Constructs [`Self`].
200    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
201        Self { slice, size }
202    }
203}
204
205impl<'a, T> IntoIterator for ChunksExact<'a, T> {
206    type Item = &'a NonEmptySlice<T>;
207
208    type IntoIter = Map<slice::ChunksExact<'a, T>, NonEmptySliceFn<'a, T>>;
209
210    fn into_iter(self) -> Self::IntoIter {
211        self.slice
212            .as_slice()
213            .chunks_exact(self.size.get())
214            // SAFETY: chunks are never empty
215            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
216    }
217}
218
219unsafe impl<T> NonEmptyIterator for ChunksExact<'_, T> {}
220
221/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
222/// starting at the beginning of the non-empty slice.
223///
224/// When the length of the non-empty slice is not divisible by the chunk size,
225/// the last chunk will be omitted.
226///
227/// This `struct` is created by the [`chunks_exact_mut`] method on [`NonEmptySlice<T>`].
228///
229/// [`chunks_exact_mut`]: NonEmptySlice::chunks_exact_mut
230#[derive(Debug)]
231pub struct ChunksExactMut<'a, T> {
232    slice: &'a mut NonEmptySlice<T>,
233    size: Size,
234}
235
236impl<'a, T> ChunksExactMut<'a, T> {
237    /// Constructs [`Self`].
238    pub const fn new(slice: &'a mut NonEmptySlice<T>, size: Size) -> Self {
239        Self { slice, size }
240    }
241}
242
243impl<'a, T> IntoIterator for ChunksExactMut<'a, T> {
244    type Item = &'a mut NonEmptySlice<T>;
245
246    type IntoIter = Map<slice::ChunksExactMut<'a, T>, NonEmptyMutSliceFn<'a, T>>;
247
248    fn into_iter(self) -> Self::IntoIter {
249        self.slice
250            .as_mut_slice()
251            .chunks_exact_mut(self.size.get())
252            // SAFETY: chunks are never empty
253            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
254    }
255}
256
257unsafe impl<T> NonEmptyIterator for ChunksExactMut<'_, T> {}
258
259/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
260/// starting at the end of the non-empty slice.
261///
262/// When the length of the non-empty slice is not divisible by the chunk size,
263/// the last chunk will be omitted.
264///
265/// This `struct` is created by the [`rchunks_exact`] method on [`NonEmptySlice<T>`].
266///
267/// [`rchunks_exact`]: NonEmptySlice::rchunks_exact
268#[derive(Debug)]
269pub struct RChunksExact<'a, T> {
270    slice: &'a NonEmptySlice<T>,
271    size: Size,
272}
273
274impl<'a, T> RChunksExact<'a, T> {
275    /// Constructs [`Self`].
276    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
277        Self { slice, size }
278    }
279}
280
281impl<'a, T> IntoIterator for RChunksExact<'a, T> {
282    type Item = &'a NonEmptySlice<T>;
283
284    type IntoIter = Map<slice::RChunksExact<'a, T>, NonEmptySliceFn<'a, T>>;
285
286    fn into_iter(self) -> Self::IntoIter {
287        self.slice
288            .as_slice()
289            .rchunks_exact(self.size.get())
290            // SAFETY: chunks are never empty
291            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
292    }
293}
294
295unsafe impl<T> NonEmptyIterator for RChunksExact<'_, T> {}
296
297/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
298/// starting at the end of the non-empty slice.
299///
300/// When the length of the non-empty slice is not divisible by the chunk size,
301/// the last chunk will be omitted.
302///
303/// This `struct` is created by the [`rchunks_exact_mut`] method on [`NonEmptySlice<T>`].
304///
305/// [`rchunks_exact_mut`]: NonEmptySlice::rchunks_exact_mut
306#[derive(Debug)]
307pub struct RChunksExactMut<'a, T> {
308    slice: &'a mut NonEmptySlice<T>,
309    size: Size,
310}
311
312impl<'a, T> RChunksExactMut<'a, T> {
313    /// Constructs [`Self`].
314    pub const fn new(slice: &'a mut NonEmptySlice<T>, size: Size) -> Self {
315        Self { slice, size }
316    }
317}
318
319impl<'a, T> IntoIterator for RChunksExactMut<'a, T> {
320    type Item = &'a mut NonEmptySlice<T>;
321
322    type IntoIter = Map<slice::RChunksExactMut<'a, T>, NonEmptyMutSliceFn<'a, T>>;
323
324    fn into_iter(self) -> Self::IntoIter {
325        self.slice
326            .as_mut_slice()
327            .rchunks_exact_mut(self.size.get())
328            // SAFETY: chunks are never empty
329            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
330    }
331}
332
333unsafe impl<T> NonEmptyIterator for RChunksExactMut<'_, T> {}
334
335/// Represents non-empty iterators over non-empty slices in (overlapping) windows.
336///
337/// This `struct` is created by the [`windows`] method on [`NonEmptySlice<T>`].
338///
339/// [`windows`]: NonEmptySlice::windows
340#[derive(Debug)]
341pub struct Windows<'a, T> {
342    slice: &'a NonEmptySlice<T>,
343    size: Size,
344}
345
346impl<'a, T> Windows<'a, T> {
347    /// Constructs [`Self`].
348    pub const fn new(slice: &'a NonEmptySlice<T>, size: Size) -> Self {
349        Self { slice, size }
350    }
351}
352
353impl<'a, T> IntoIterator for Windows<'a, T> {
354    type Item = &'a NonEmptySlice<T>;
355
356    type IntoIter = Map<slice::Windows<'a, T>, NonEmptySliceFn<'a, T>>;
357
358    fn into_iter(self) -> Self::IntoIter {
359        self.slice
360            .as_slice()
361            .windows(self.size.get())
362            // SAFETY: windows are never empty
363            .map(|window| unsafe { NonEmptySlice::from_slice_unchecked(window) })
364    }
365}
366
367unsafe impl<T> NonEmptyIterator for Windows<'_, T> {}
368
369/// Represents non-empty iterators over non-empty slices in (non-overlapping) chunks,
370/// separated by the given predicate.
371///
372/// This `struct` is created by the [`chunk_by`] method on [`NonEmptySlice<T>`].
373///
374/// [`chunk_by`]: NonEmptySlice::chunk_by
375pub struct ChunkBy<'a, T, P: FnMut(&T, &T) -> bool> {
376    slice: &'a NonEmptySlice<T>,
377    predicate: P,
378}
379
380impl<T: fmt::Debug, P: FnMut(&T, &T) -> bool> fmt::Debug for ChunkBy<'_, T, P> {
381    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
382        formatter
383            .debug_struct(stringify!(ChunkBy))
384            .field(stringify!(slice), &self.slice)
385            .finish()
386    }
387}
388
389impl<'a, T, P: FnMut(&T, &T) -> bool> ChunkBy<'a, T, P> {
390    /// Constructs [`Self`].
391    pub const fn new(slice: &'a NonEmptySlice<T>, predicate: P) -> Self {
392        Self { slice, predicate }
393    }
394}
395
396impl<'a, T, P: FnMut(&T, &T) -> bool> IntoIterator for ChunkBy<'a, T, P> {
397    type Item = &'a NonEmptySlice<T>;
398
399    type IntoIter = Map<slice::ChunkBy<'a, T, P>, NonEmptySliceFn<'a, T>>;
400
401    fn into_iter(self) -> Self::IntoIter {
402        self.slice
403            .as_slice()
404            .chunk_by(self.predicate)
405            // SAFETY: chunks are never empty
406            .map(|chunk| unsafe { NonEmptySlice::from_slice_unchecked(chunk) })
407    }
408}
409
410unsafe impl<T, P: FnMut(&T, &T) -> bool> NonEmptyIterator for ChunkBy<'_, T, P> {}
411
412/// Represents non-empty iterators over non-empty slices in (non-overlapping) mutable chunks,
413/// separated by the given predicate.
414///
415/// This `struct` is created by the [`chunk_by_mut`] method on [`NonEmptySlice<T>`].
416///
417/// [`chunk_by_mut`]: NonEmptySlice::chunk_by_mut
418pub struct ChunkByMut<'a, T, P: FnMut(&T, &T) -> bool> {
419    slice: &'a mut NonEmptySlice<T>,
420    predicate: P,
421}
422
423impl<T: fmt::Debug, P: FnMut(&T, &T) -> bool> fmt::Debug for ChunkByMut<'_, T, P> {
424    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
425        formatter
426            .debug_struct(stringify!(ChunkByMut))
427            .field(stringify!(slice), &self.slice)
428            .finish()
429    }
430}
431
432impl<'a, T, P: FnMut(&T, &T) -> bool> ChunkByMut<'a, T, P> {
433    /// Constructs [`Self`].
434    pub const fn new(slice: &'a mut NonEmptySlice<T>, predicate: P) -> Self {
435        Self { slice, predicate }
436    }
437}
438
439impl<'a, T, P: FnMut(&T, &T) -> bool> IntoIterator for ChunkByMut<'a, T, P> {
440    type Item = &'a mut NonEmptySlice<T>;
441
442    type IntoIter = Map<slice::ChunkByMut<'a, T, P>, NonEmptyMutSliceFn<'a, T>>;
443
444    fn into_iter(self) -> Self::IntoIter {
445        self.slice
446            .as_mut_slice()
447            .chunk_by_mut(self.predicate)
448            // SAFETY: chunks are never empty
449            .map(|chunk| unsafe { NonEmptySlice::from_mut_slice_unchecked(chunk) })
450    }
451}
452
453unsafe impl<T, P: FnMut(&T, &T) -> bool> NonEmptyIterator for ChunkByMut<'_, T, P> {}
454
455/// Represents non-empty iterators that produce escaped versions of provided slices,
456/// treating them as ASCII strings.
457///
458/// This `struct` is created by the [`escape_ascii`] method on [`NonEmptyBytes`].
459///
460/// [`escape_ascii`]: NonEmptyBytes::escape_ascii
461#[derive(Debug)]
462pub struct EscapeAscii<'a> {
463    bytes: &'a NonEmptyBytes,
464}
465
466impl<'a> EscapeAscii<'a> {
467    /// Constructs [`Self`].
468    #[must_use]
469    pub const fn new(bytes: &'a NonEmptyBytes) -> Self {
470        Self { bytes }
471    }
472}
473
474impl<'a> IntoIterator for EscapeAscii<'a> {
475    type Item = u8;
476
477    type IntoIter = slice::EscapeAscii<'a>;
478
479    fn into_iter(self) -> Self::IntoIter {
480        self.bytes.as_slice().escape_ascii()
481    }
482}
483
484unsafe impl NonEmptyIterator for EscapeAscii<'_> {}