nunny/
iter.rs

1use core::{
2    cmp::Ordering,
3    iter::{
4        Chain, Cloned, Copied, Cycle, Enumerate, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Take,
5    },
6    num::NonZeroUsize,
7};
8
9use crate::NonEmpty;
10
11macro_rules! unwrap {
12    ($expr:expr) => {
13        match $expr {
14            Some(it) => it,
15            // Safety:
16            // - NonEmpty<impl Iterator> is only constructed from known NonEmpty items
17            // - NonEmpty<impl Iterator> does give out mutable access to the inner iterator
18            //   (so it always has one element)
19            None => unsafe { crate::unreachable() },
20        }
21    };
22}
23
24/// Methods on [`Iterator`]s with a non-empty invariant.
25///
26/// See [`Self::relax`] to access the normal iterator inside.
27impl<I> NonEmpty<I>
28where
29    I: Iterator,
30{
31    /// [`NonEmpty`] version of [`Iterator::next`].
32    /// ```
33    /// # use nunny::{vec};
34    /// let v = vec![1, 2, 3];
35    /// let _: Option<&u8> = v.iter().next();
36    ///     // ^ normally you have to handle the empty case
37    /// let _: &u8 = v.iter_ne().first();
38    ///     // ^ but we know there is at least one element
39    /// ```
40    pub fn first(mut self) -> I::Item {
41        unwrap!(self.inner.next())
42    }
43    /// [`NonEmpty`] version of [`Iterator::last`].
44    /// ```
45    /// # use nunny::{vec};
46    /// let v = vec![1, 2, 3];
47    /// let _: Option<&u8> = v.iter().last();
48    ///     // ^ normally you have to handle the empty case
49    /// let _: &u8 = v.iter_ne().last();
50    ///     // ^ but we know there is at least one element
51    /// ```
52    pub fn last(self) -> I::Item {
53        unwrap!(self.inner.last())
54    }
55    /// [`NonEmpty`] version of [`Iterator::map`].
56    /// ```
57    /// # use nunny::{slice};
58    /// let iter = slice![1, 2, 3].iter_ne();
59    /// assert_eq!(
60    ///     iter.map(|it| *it * 2).last(),
61    ///                         // ^ the invariant is maintained
62    ///                         //   so we _know_ there's a last element
63    ///     6
64    /// );
65    /// ```
66    pub fn map<B, F>(self, f: F) -> NonEmpty<Map<I, F>>
67    where
68        F: FnMut(I::Item) -> B,
69    {
70        NonEmpty {
71            inner: self.inner.map(f),
72        }
73    }
74    /// [`NonEmpty`] version of [`Iterator::chain`].
75    /// ```
76    /// # use nunny::{slice};
77    /// let iter = slice![1, 2].iter_ne();
78    /// assert_eq!(
79    ///     iter.chain(&[3]).last(),
80    ///                   // ^ the invariant is maintained
81    ///                   //   so we _know_ there's a last element
82    ///     &3
83    /// );
84    /// ```
85    pub fn chain<U>(self, other: U) -> NonEmpty<Chain<I, <U as IntoIterator>::IntoIter>>
86    where
87        U: IntoIterator<Item = I::Item>,
88    {
89        NonEmpty {
90            inner: self.inner.chain(other),
91        }
92    }
93    /// [`NonEmpty`] version of [`Iterator::enumerate`].
94    /// ```
95    /// # use nunny::{slice};
96    /// let iter = slice!['a', 'b'].iter_ne();
97    /// assert_eq!(
98    ///     iter.enumerate().last(),
99    ///                  // ^ the invariant is maintained
100    ///                  //   so we _know_ there's a last element
101    ///     (1, &'b')
102    /// );
103    /// ```
104    pub fn enumerate(self) -> NonEmpty<Enumerate<I>> {
105        NonEmpty {
106            inner: self.inner.enumerate(),
107        }
108    }
109    /// [`NonEmpty`] version of [`Iterator::peekable`], allowing you to use
110    /// [`Self::peek`] and [`Self::peek_mut`]
111    /// ```
112    /// # use nunny::{vec, NonEmpty};
113    /// let mut peek_me = vec!['a', 'b'].into_iter_ne().peekable();
114    /// assert_eq!(
115    ///     *peek_me.peek(),
116    ///     'a'
117    /// );
118    /// *peek_me.peek_mut() = 'b';
119    /// assert_eq!(
120    ///     peek_me.collect_vec(),
121    ///     ['b', 'b']
122    /// );
123    /// ```
124    pub fn peekable(self) -> NonEmpty<Peekable<I>> {
125        NonEmpty {
126            inner: self.inner.peekable(),
127        }
128    }
129    /// [`NonEmpty`] version of [`Iterator::take`].
130    ///
131    /// Note that `n` cannot be zero, to maintain the [`NonEmpty`] invariant.
132    ///
133    /// ```
134    /// # use nunny::{slice, nonzero};
135    /// let iter = slice!['a', 'b'].iter_ne();
136    /// assert_eq!(
137    ///     iter.take(nonzero!(1)).last(),
138    ///            // ^ compile time checked
139    ///     &'a'
140    /// )
141    /// ```
142    pub fn take(self, n: NonZeroUsize) -> NonEmpty<Take<I>> {
143        NonEmpty {
144            inner: self.inner.take(n.get()),
145        }
146    }
147    // pub fn flat_map
148    /// [`NonEmpty`] version of [`Iterator::flatten`].
149    ///
150    /// Note that the inner items must also be [`NonEmpty`], to maintain the invariant.
151    /// ```
152    /// use nunny::{vec};
153    /// let nested = vec![vec![1], vec![2, 3]];
154    /// assert_eq!(
155    ///     nested.into_iter_ne().flatten().collect_vec(),
156    ///     [1, 2, 3],
157    /// );
158    /// ```
159    #[allow(clippy::type_complexity)]
160    pub fn flatten<II, T>(self) -> NonEmpty<FlatMap<I, II, fn(I::Item) -> II>>
161    where
162        I: Iterator<Item = NonEmpty<II>>,
163        //                 ^ each item is nonempty
164        II: IntoIterator<Item = T>,
165        // TODO(aatifsyed): a trait NonEmptyIterator would make this more ergonomic
166        //                  See commit history for an attempt
167    {
168        NonEmpty {
169            inner: self.inner.flat_map(|it| it.inner),
170        }
171    }
172    /// [`NonEmpty`] version of [`Iterator::fuse`].
173    pub fn fuse(self) -> NonEmpty<Fuse<I>> {
174        NonEmpty {
175            inner: self.inner.fuse(),
176        }
177    }
178    /// [`NonEmpty`] version of [`Iterator::inspect`].
179    pub fn inspect<F>(self, f: F) -> NonEmpty<Inspect<I, F>>
180    where
181        F: FnMut(&I::Item),
182    {
183        NonEmpty {
184            inner: self.inner.inspect(f),
185        }
186    }
187    /// [`NonEmpty`] version of [`Iterator::reduce`].
188    /// ```
189    /// # use nunny::{vec};
190    /// # use core::cmp::min;
191    /// let v = vec![1, 2, 3];
192    /// let _: Option<&u8> = v.iter().reduce(min);
193    ///     // ^ normally you have to handle the empty case
194    /// let _: &u8 = v.iter_ne().reduce(min);
195    ///     // ^ but we know there is at least one element
196    /// ```
197    pub fn reduce<F>(self, f: F) -> I::Item
198    where
199        F: FnMut(I::Item, I::Item) -> I::Item,
200    {
201        unwrap!(self.inner.reduce(f))
202    }
203    /// [`NonEmpty`] version of [`Iterator::max`].
204    /// ```
205    /// # use nunny::{vec};
206    /// let v = vec![1, 2, 3];
207    /// let _: Option<&u8> = v.iter().max();
208    ///     // ^ normally you have to handle the empty case
209    /// let _: &u8 = v.iter_ne().max();
210    ///     // ^ but we know there is at least one element
211    /// ```
212    pub fn max(self) -> I::Item
213    where
214        I::Item: Ord,
215    {
216        unwrap!(self.inner.max())
217    }
218    /// [`NonEmpty`] version of [`Iterator::min`].
219    /// ```
220    /// # use nunny::{vec};
221    /// let v = vec![1, 2, 3];
222    /// let _: Option<&u8> = v.iter().min();
223    ///     // ^ normally you have to handle the empty case
224    /// let _: &u8 = v.iter_ne().min();
225    ///     // ^ but we know there is at least one element
226    /// ```
227    pub fn min(self) -> I::Item
228    where
229        I::Item: Ord,
230    {
231        unwrap!(self.inner.min())
232    }
233    /// [`NonEmpty`] version of [`Iterator::max_by_key`].
234    pub fn max_by_key<B, F>(self, f: F) -> I::Item
235    where
236        B: Ord,
237        F: FnMut(&I::Item) -> B,
238    {
239        unwrap!(self.inner.max_by_key(f))
240    }
241    /// [`NonEmpty`] version of [`Iterator::max_by`].
242    pub fn max_by<F>(self, compare: F) -> I::Item
243    where
244        F: FnMut(&I::Item, &I::Item) -> Ordering,
245    {
246        unwrap!(self.inner.max_by(compare))
247    }
248    /// [`NonEmpty`] version of [`Iterator::min_by_key`].
249    pub fn min_by_key<B, F>(self, f: F) -> I::Item
250    where
251        B: Ord,
252        F: FnMut(&I::Item) -> B,
253    {
254        unwrap!(self.inner.min_by_key(f))
255    }
256    /// [`NonEmpty`] version of [`Iterator::min_by`].
257    pub fn min_by<F>(self, compare: F) -> I::Item
258    where
259        F: FnMut(&I::Item, &I::Item) -> Ordering,
260    {
261        unwrap!(self.inner.min_by(compare))
262    }
263    /// [`NonEmpty`] version of [`Iterator::rev`].
264    pub fn rev(self) -> NonEmpty<Rev<I>>
265    where
266        I: DoubleEndedIterator,
267    {
268        NonEmpty {
269            inner: self.inner.rev(),
270        }
271    }
272
273    /// [`NonEmpty`] version of [`Iterator::unzip`].
274    #[cfg(feature = "alloc")]
275    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
276    pub fn unzip_vec<A, B>(self) -> (crate::Vec<A>, crate::Vec<B>)
277    where
278        I: Iterator<Item = (A, B)>,
279    {
280        let (a, b) = self.inner.unzip();
281        // Safety:
282        // - NonEmpty<impl Iterator> is only constructed from known NonEmpty items
283        // - NonEmpty<impl Iterator> does not allow mutable access to the inner iterator
284        //   (so it always has one element)
285        unsafe { (crate::Vec::new_unchecked(a), crate::Vec::new_unchecked(b)) }
286    }
287    /// [`NonEmpty`] version of [`Iterator::copied`].
288    pub fn copied<'a, T>(self) -> NonEmpty<Copied<I>>
289    where
290        T: 'a + Copy,
291        I: Iterator<Item = &'a T>,
292    {
293        NonEmpty {
294            inner: self.inner.copied(),
295        }
296    }
297    /// [`NonEmpty`] version of [`Iterator::cloned`].
298    pub fn cloned<'a, T>(self) -> NonEmpty<Cloned<I>>
299    where
300        T: 'a + Clone,
301        I: Iterator<Item = &'a T>,
302    {
303        NonEmpty {
304            inner: self.inner.cloned(),
305        }
306    }
307    /// [`NonEmpty`] version of [`Iterator::cycle`].
308    pub fn cycle(self) -> NonEmpty<Cycle<I>>
309    where
310        I: Clone,
311    {
312        NonEmpty {
313            inner: self.inner.cycle(),
314        }
315    }
316    /// Remove the [`NonEmpty`] wrapper, allowing you to access normal iterator
317    /// methods like [`Iterator::filter`].
318    #[doc(alias = "into_iter")]
319    #[doc(alias = "into_inner")]
320    pub fn relax(self) -> I {
321        self.inner
322    }
323    /// Collect this iterator into a [`NonEmpty<Vec>`].
324    #[cfg(feature = "alloc")]
325    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
326    pub fn collect_vec(self) -> crate::Vec<I::Item> {
327        // Safety:
328        // - NonEmpty<impl Iterator> is only constructed from known NonEmpty items
329        // - NonEmpty<impl Iterator> does not allow mutable access to the inner iterator
330        //   (so it always has one element)
331        unsafe { crate::Vec::new_unchecked(self.inner.collect()) }
332    }
333    /// Collect [`Ok`] items into a [`NonEmpty<Vec>`], short-circuiting on [`Err`].
334    #[cfg(feature = "alloc")]
335    #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
336    pub fn try_collect_vec<T, E>(self) -> Result<crate::Vec<T>, E>
337    where
338        I: Iterator<Item = Result<T, E>>,
339    {
340        match self.inner.collect() {
341            // Safety:
342            // - NonEmpty<impl Iterator> is only constructed from known NonEmpty items
343            // - NonEmpty<impl Iterator> does not allow mutable access to the inner iterator
344            //   (so it always has one element)
345            Ok(it) => Ok(unsafe { crate::Vec::new_unchecked(it) }),
346            Err(e) => Err(e),
347        }
348    }
349}
350
351impl<I> NonEmpty<Peekable<I>>
352where
353    I: Iterator,
354{
355    /// Peek this [`NonEmpty`] iterator, without advancing it.
356    ///
357    /// See [`Self::peekable`].
358    pub fn peek(&mut self) -> &I::Item {
359        unwrap!(self.inner.peek())
360    }
361    /// Peek and modify this [`NonEmpty`] iterator, without advancing it.
362    ///
363    /// See [`Self::peekable`].
364    pub fn peek_mut(&mut self) -> &mut I::Item {
365        unwrap!(self.inner.peek_mut())
366    }
367}