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}