first_err/
lib.rs

1//! # `first-err`
2//!
3//! Find the first `Err` in `Iterator<Item = Result<T, E>>` and allow iterating continuously.
4//!
5//! This crate is specifically designed to replace the following pattern without allocation:
6//!
7//! ```txt
8//! // iter: impl Iterator<Item = Result<T, E>>
9//! iter.collect::<Result<Vec<T>, E>>().map(|vec| vec.into_iter().foo() );
10//! ```
11//!
12//! See [`FirstErr`] trait for more detail.
13//!
14//!
15//!
16//! ## Features
17//!
18//! - Easy-to-use: simple and no way to using wrong.
19//! - Minimized: no `std`, no `alloc`, zero dependency.
20//! - Fast: Roughly on par with a hand-written loop, using lazy evaluation and no allocation.
21//! - Nestable: `T` in `Iterator<Item = Result<T, E>>` can lazily produce more `Result`s.
22//!
23//!
24//!
25//! ## Getting Started
26//!
27//! ```rust
28//! // Use this trait in current scope.
29//! use first_err::FirstErr;
30//!
31//! # fn main() {
32//! // Everything is Ok.
33//! let result = [Ok::<u8, u8>(0), Ok(1), Ok(2)]
34//!     .into_iter()
35//!     .first_err_or_else(|iter| iter.sum::<u8>());
36//! assert_eq!(result, Ok(3));
37//!
38//! // Contains some `Err` values.
39//! let result = [Ok::<u8, u8>(0), Err(1), Err(2)]
40//!     .into_iter()
41//!     .first_err_or_else(|iter| iter.sum::<u8>());
42//! assert_eq!(result, Err(1));
43//! # }
44//! ```
45//!
46//!
47//!
48//! ## Why
49//!
50//! In Rust, I frequently encounter a pattern where I need to perform actions on all
51//! items within an iterator, and halt immediately if any error is detected in the layer
52//! I'm working on. But if no error found, the iterator should able to run continuously
53//! and allow me to do further transform.
54//!
55//! The pattern typically looks as follows:
56//!
57//! ```rust
58//! # fn main() {
59//! let array: [Result<u8, u8>; 3] = [Ok(0), Err(1), Err(2)];
60//!
61//! fn fallible_sum(iter: impl IntoIterator<Item = Result<u8, u8>>) -> Result<u8, u8> {
62//!     let sum = iter
63//!         .into_iter()
64//!         .collect::<Result<Vec<_>, _>>()?    // early return (and a vec alloc in here)
65//!         .into_iter()                        // continue iterate next layer ...
66//!         .sum();
67//!
68//!     Ok(sum)
69//! }
70//!
71//! let result = fallible_sum(array);
72//! assert_eq!(result, Err(1));
73//! # }
74//! ```
75//!
76//! In theory, this allocation is not necessary. We can just write that code as an old good
77//! loop:
78//!
79//! ```rust
80//! # fn main() {
81//! let array: [Result<u8, u8>; 3] = [Ok(0), Err(1), Err(2)];
82//!
83//! fn fallible_sum(iter: impl IntoIterator<Item = Result<u8, u8>>) -> Result<u8, u8> {
84//!     let mut sum = 0;
85//!     for res in iter {
86//!         let val = res?;                     // early return, no alloc
87//!         sum += val;
88//!     }
89//!
90//!     Ok(sum)
91//! }
92//!
93//! let result = fallible_sum(array);
94//! assert_eq!(result, Err(1))
95//! # }
96//! ```
97//!
98//! Using a loop is not bad at all. However, in some situations, maintaining a chainable
99//! iterator is preferable.
100//!
101//! Furthermore, some scenarios may not be as simple as the previous example. Consider this one:
102//!
103//! ```rust
104//! # fn main() {
105//! // The second layer `Result` is usually created by further transform after the first layer
106//! // `Result` be processed. But for the sake of simplicity, we've just use pre-defined values.
107//! let array: [Result<Result<u8, u8>, u8>; 3] = [Ok(Ok(0)), Ok(Err(1)), Err(2)];
108//!
109//! fn fallible_sum(
110//!     iter: impl IntoIterator<Item = Result<Result<u8, u8>, u8>>
111//! ) -> Result<u8, u8> {
112//!     // take "first `Err`" layer by layer, or the sum value.
113//!     let sum = iter
114//!         .into_iter()
115//!         .collect::<Result<Vec<Result<u8, u8>>, u8>>()?
116//!         .into_iter()
117//!         .collect::<Result<Vec<u8>, u8>>()?
118//!         .into_iter()
119//!         .sum();
120//!
121//!     Ok(sum)
122//! }
123//!
124//! let result = fallible_sum(array);
125//! assert_eq!(result, Err(2));
126//! # }
127//! ```
128//!
129//! Implementing the above logic in a loop without allocation may be
130//! [error-prone and complicated](https://github.com/visig9/first-err/blob/f666ef16c0b72174e7862468f1dbda382ebe6b68/benches/benchmark.rs#L194-L231).
131//! This crate simplifies that for you:
132//!
133//! ```rust
134//! # use first_err::FirstErr;
135//! #
136//! # fn main() {
137//! let array: [Result<Result<u8, u8>, u8>; 3] = [Ok(Ok(0)), Ok(Err(1)), Err(2)];
138//!
139//! fn fallible_sum(
140//!     iter: impl IntoIterator<Item = Result<Result<u8, u8>, u8>>
141//! ) -> Result<u8, u8> {
142//!     iter
143//!         .into_iter()
144//!         .first_err_or_try(|iter1| { // iter1 = impl Iterator<Item = Result<u8, u8>>
145//!             iter1.first_err_or_else(|iter2| { // iter2 = impl Iterator<Item = u8>
146//!                 iter2.sum::<u8>()
147//!             })
148//!         })
149//! }
150//!
151//! let result = fallible_sum(array);
152//! assert_eq!(result, Err(2));
153//! # }
154//! ```
155//!
156//!
157//!
158//! ## Performance
159//!
160//! The performance of this crate is designed to be roughly on par with hand-written loops.
161//! However, the compiler might apply different optimizations in various situations, and favoring
162//! one approach over the others.
163//!
164//! If you want to to do a benchmark by yourself, use the following command:
165//!
166//! ```sh
167//! cargo bench --bench benchmark -- --output-format bencher
168//! ```
169//!
170//! Also, don't forget to check the actual code that is used for benchmarking, which is in the
171//! `benches` folder.
172
173#![no_std]
174
175pub use option::FirstNoneIter;
176pub use result::FirstErrIter;
177
178/// This trait provides some methods on any `Iterator<Item = Result<T, E>>`, which can take
179/// the first `Err` in iterators, and without allocation.
180///
181/// `Iterator<Item = Option<T>>` version with the same logic are also supported.
182///
183///
184///
185/// ## Guarantees
186///
187/// There are some methods in `FirstErr` trait take a closure that accepts an iterator
188/// as its argument. This crate guarantees all those methods have the following properties.
189///
190///
191///
192/// ### Original Iterator is Evaluated Lazily
193///
194/// The `.next()` of the original iterator only be called as late as possible, For example,
195///
196/// ```rust
197/// # use first_err::FirstErr;
198/// # use std::cell::RefCell;
199/// #
200/// # fn main() {
201/// let mut vec = RefCell::new(vec![]);
202///
203/// let mut result = [Ok::<u8, u8>(0), Ok(1), Err(2), Ok(3)]
204///     .into_iter()
205///     .inspect(|res| { vec.borrow_mut().push(*res) })         // push value from outer
206///     .first_err_or_else(|iter| {
207///         iter
208///             .inspect(|n| { vec.borrow_mut().push(Ok(42)) }) // push value from inner
209///             .sum::<u8>()
210///     });
211///
212/// assert_eq!(result, Err(2));
213/// assert_eq!(
214///     vec.into_inner(),
215///     vec![Ok(0), Ok(42), Ok(1), Ok(42), Err(2)],
216/// );
217/// # }
218/// ```
219///
220///
221///
222/// ### No Need to Manually Consume the Closure's Iterator
223///
224/// User can simple ignore the iterator in closure partially of fully, and still can get
225/// the correct result.
226///
227/// ```rust
228/// # use first_err::FirstErr;
229/// #
230/// # fn main() {
231/// let result = [Ok::<u8, u8>(0), Err(1), Err(2)]
232///     .into_iter()
233///     .first_err_or_else(|_iter| {}); // not need to consume `_iter` iterator,
234/// assert_eq!(result, Err(1));         // and the result still correct.
235/// # }
236/// ```
237///
238///
239///
240/// ### Iterator in Closure Can't be Leaked Out of Closure Scope
241///
242/// Let the iterator in closure escaped from the closure is a compiler error.
243///
244/// ```rust,compile_fail
245/// # use first_err::FirstErr;
246/// #
247/// # fn main() {
248/// let iter = [Ok::<u8, u8>(0), Err(1), Err(2)]
249///     .into_iter()
250///     .first_err_or_else(|iter| iter); // compile error: can't leak `iter` out
251/// # }
252/// ```
253pub trait FirstErr: Iterator {
254    /// Returns the first `Err` item in the current iterator, or an `Ok` value produced by the
255    /// `f` closure.
256    ///
257    /// The argument iterator of the `f` closure will producing the same values in `Ok` sequence,
258    /// but will stop when encounter the first `Err` item.
259    ///
260    ///
261    ///
262    /// # Examples
263    ///
264    /// ```rust
265    /// use first_err::FirstErr;
266    ///
267    /// # fn main() {
268    /// // Everything is Ok.
269    /// let result = [Ok::<u8, u8>(0), Ok(1), Ok(2)]
270    ///     .into_iter()
271    ///     .first_err_or_else(|iter| iter.sum::<u8>());
272    /// assert_eq!(result, Ok(3));
273    ///
274    /// // Contains some `Err` values.
275    /// let result = [Ok::<u8, u8>(0), Err(1), Err(2)]
276    ///     .into_iter()
277    ///     .first_err_or_else(|iter| iter.sum::<u8>());
278    /// assert_eq!(result, Err(1));
279    /// # }
280    /// ```
281    #[inline]
282    fn first_err_or_else<T, E, O, F>(self, f: F) -> Result<O, E>
283    where
284        F: FnOnce(&mut FirstErrIter<Self, T, E>) -> O,
285        Self: Iterator<Item = Result<T, E>> + Sized,
286    {
287        FirstErrIter::first_err_or_else(self, f)
288    }
289
290    /// Returns the first `Err` item in the current iterator, or an `Result` value produced
291    /// by the `f` closure.
292    ///
293    /// The argument iterator of the `f` closure will producing the same values in `Ok` sequence,
294    /// but will stop when encounter the first `Err` item.
295    ///
296    ///
297    ///
298    /// # Examples
299    ///
300    /// Basic concept:
301    ///
302    /// ```rust
303    /// use first_err::FirstErr;
304    ///
305    /// # fn main() {
306    /// // Everything is Ok.
307    /// let result = [Ok::<u8, u8>(0), Ok(1), Ok(2)]
308    ///     .into_iter()
309    ///     .first_err_or_try(|_| Ok("ok"));
310    /// assert_eq!(result, Ok("ok"));
311    ///
312    /// // When closure returns Err.
313    /// let result = [Ok::<u8, u8>(0), Ok(1), Ok(2)]
314    ///     .into_iter()
315    ///     .first_err_or_try(|_| Err::<u8, u8>(42));
316    /// assert_eq!(result, Err(42));
317    ///
318    /// // When outer iterator contains Err.
319    /// let result = [Ok::<u8, u8>(0), Err(2), Ok(2)]
320    ///     .into_iter()
321    ///     .first_err_or_try(|_| Ok("ok"));
322    /// assert_eq!(result, Err(2));
323    ///
324    /// // When both contains Err.
325    /// let result = [Ok::<u8, u8>(0), Err(1), Ok(2)]
326    ///     .into_iter()
327    ///     .first_err_or_try(|_| Err::<u8, u8>(42));
328    /// assert_eq!(result, Err(1));
329    /// # }
330    /// ```
331    ///
332    /// Use the `iter` argument of the `f` closure:
333    ///
334    /// ```rust
335    /// # use first_err::FirstErr;
336    /// #
337    /// # fn main() {
338    /// let admin_id: u32 = 1;
339    /// let user_ids_in_conf = ["32", "5", "8", "19"];
340    ///
341    /// let admin_index = user_ids_in_conf
342    ///     .into_iter()
343    ///     .map(|s| s.parse::<u32>().map_err(|_| "user id parsing failed"))
344    ///     .first_err_or_try(|user_ids_iter| {
345    ///         user_ids_iter
346    ///             .position(|user_id| user_id == admin_id)
347    ///             .ok_or_else(|| "admin not in the user list")
348    ///     });
349    ///
350    /// assert_eq!(admin_index, Err("admin not in the user list"));
351    /// # }
352    /// ```
353    #[inline]
354    fn first_err_or_try<T, E, O, F>(self, f: F) -> Result<O, E>
355    where
356        F: FnOnce(&mut FirstErrIter<Self, T, E>) -> Result<O, E>,
357        Self: Iterator<Item = Result<T, E>> + Sized,
358    {
359        self.first_err_or_else(f).and_then(|res| res)
360    }
361
362    /// Returns the first `Err` item in the current iterator, or an `Ok(value)`.
363    ///
364    ///
365    ///
366    /// # Examples
367    ///
368    /// ```rust
369    /// # use first_err::FirstErr;
370    /// #
371    /// # fn main() {
372    /// // Everything is Ok.
373    /// let result = [Ok::<u8, u8>(0), Ok(1), Ok(2)]
374    ///     .into_iter()
375    ///     .first_err_or("foo");
376    /// assert_eq!(result, Ok("foo"));
377    ///
378    /// // Contains some `Err` values.
379    /// let result = [Ok::<u8, u8>(0), Err(1), Err(2)]
380    ///     .into_iter()
381    ///     .first_err_or("foo");
382    /// assert_eq!(result, Err(1));
383    /// # }
384    /// ```
385    #[inline]
386    fn first_err_or<T, E, O>(self, value: O) -> Result<O, E>
387    where
388        Self: Iterator<Item = Result<T, E>> + Sized,
389    {
390        self.first_err_or_else(|_| value)
391    }
392
393    /// Returns the first `None` item in the current iterator, or an `Some` value produced
394    /// by the `f` closure.
395    ///
396    /// The argument iterator of the `f` closure will producing the same values in `Some` sequence,
397    /// but will stop when encounter the first `None` item.
398    ///
399    ///
400    ///
401    /// # Examples
402    ///
403    /// ```rust
404    /// use first_err::FirstErr;
405    ///
406    /// # fn main() {
407    /// // Everything is Some.
408    /// let option = [Some::<u8>(0), Some(1), Some(2)]
409    ///     .into_iter()
410    ///     .first_none_or_else(|iter| iter.sum::<u8>());
411    /// assert_eq!(option, Some(3));
412    ///
413    /// // Contains some `None` values.
414    /// let option = [Some::<u8>(0), None, None]
415    ///     .into_iter()
416    ///     .first_none_or_else(|iter| iter.sum::<u8>());
417    /// assert_eq!(option, None);
418    /// # }
419    /// ```
420    #[inline]
421    fn first_none_or_else<T, O, F>(self, f: F) -> Option<O>
422    where
423        F: FnOnce(&mut FirstNoneIter<Self, T>) -> O,
424        Self: Iterator<Item = Option<T>> + Sized,
425    {
426        FirstNoneIter::first_none_or_else(self, f)
427    }
428
429    /// Returns the first `None` item in the current iterator, or an `Option` value produced
430    /// by the `f` closure.
431    ///
432    /// The argument iterator of the `f` closure will producing the same values in `Some` sequence,
433    /// but will stop when encounter the first `None` item.
434    ///
435    ///
436    ///
437    /// # Examples
438    ///
439    /// Basic concept:
440    ///
441    /// ```rust
442    /// use first_err::FirstErr;
443    ///
444    /// # fn main() {
445    /// // Everything is Some.
446    /// let option = [Some::<u8>(0), Some(1), Some(2)]
447    ///     .into_iter()
448    ///     .first_none_or_try(|_| Some("ok"));
449    /// assert_eq!(option, Some("ok"));
450    ///
451    /// // When closure returns None.
452    /// let option: Option<&str> = [Some::<u8>(0), Some(1), Some(2)]
453    ///     .into_iter()
454    ///     .first_none_or_try(|_| None);
455    /// assert_eq!(option, None);
456    ///
457    /// // When outer iterator contains None.
458    /// let option = [Some::<u8>(0), None, Some(2)]
459    ///     .into_iter()
460    ///     .first_none_or_try(|_| Some("ok"));
461    /// assert_eq!(option, None);
462    ///
463    /// // When both contains None.
464    /// let option: Option<&str> = [Some::<u8>(0), None, Some(2)]
465    ///     .into_iter()
466    ///     .first_none_or_try(|_| None);
467    /// assert_eq!(option, None);
468    /// # }
469    /// ```
470    ///
471    /// Use the `iter` argument of the `f` closure:
472    ///
473    /// ```rust
474    /// # use first_err::FirstErr;
475    /// #
476    /// # fn main() {
477    /// let admin_id: u32 = 1;
478    /// let user_ids_in_conf = ["32", "5", "8", "19"];
479    ///
480    /// let admin_index = user_ids_in_conf
481    ///     .into_iter()
482    ///     .map(|s| s.parse::<u32>().ok())
483    ///     .first_none_or_try(|user_ids_iter| {
484    ///         user_ids_iter
485    ///             .position(|user_id| user_id == admin_id)
486    ///     });
487    ///
488    /// assert_eq!(admin_index, None);
489    /// # }
490    /// ```
491    #[inline]
492    fn first_none_or_try<T, O, F>(self, f: F) -> Option<O>
493    where
494        F: FnOnce(&mut FirstNoneIter<Self, T>) -> Option<O>,
495        Self: Iterator<Item = Option<T>> + Sized,
496    {
497        self.first_none_or_else(f).and_then(|opt| opt)
498    }
499
500    /// Returns the first `None` item in the current iterator, or an `Some(value)`.
501    ///
502    ///
503    ///
504    /// # Examples
505    ///
506    /// ```rust
507    /// # use first_err::FirstErr;
508    /// #
509    /// # fn main() {
510    /// // Everything is Some.
511    /// let option = [Some::<u8>(0), Some(1), Some(2)]
512    ///     .into_iter()
513    ///     .first_none_or("foo");
514    /// assert_eq!(option, Some("foo"));
515    ///
516    /// // Contains some `None` values.
517    /// let option = [Some::<u8>(0), None, None]
518    ///     .into_iter()
519    ///     .first_none_or("foo");
520    /// assert_eq!(option, None);
521    /// # }
522    /// ```
523    #[inline]
524    fn first_none_or<T, O>(self, value: O) -> Option<O>
525    where
526        Self: Iterator<Item = Option<T>> + Sized,
527    {
528        self.first_none_or_else(|_| value)
529    }
530}
531
532impl<I> FirstErr for I where I: Iterator {}
533
534mod result {
535    use core::iter::FusedIterator;
536
537    /// An `Iterator` can take first `Err` from another iterator.
538    ///
539    /// See [`FirstErr::first_err_or_else()`](crate::FirstErr::first_err_or_else) for more details.
540    #[derive(Debug)]
541    pub struct FirstErrIter<I, T, E>
542    where
543        I: Iterator<Item = Result<T, E>>,
544    {
545        state: State<I, T, E>,
546    }
547
548    impl<I, T, E> FirstErrIter<I, T, E>
549    where
550        I: Iterator<Item = Result<T, E>>,
551    {
552        #[inline]
553        pub(super) fn first_err_or_else<O, F>(inner: I, f: F) -> Result<O, E>
554        where
555            F: FnOnce(&mut Self) -> O,
556        {
557            let mut me = Self {
558                state: State::Active(inner),
559            };
560
561            let output = f(&mut me);
562
563            // Take first err, if not found and not exhausted yet, find it.
564            // If just not found finally, return output.
565            match me.state {
566                State::Active(inner) => {
567                    for res in inner {
568                        let _ = res?;
569                    }
570                    Ok(output)
571                }
572                State::Exhausted => Ok(output),
573                State::FoundFirstErr(e) => Err(e),
574            }
575        }
576    }
577
578    impl<I, T, E> Iterator for FirstErrIter<I, T, E>
579    where
580        I: Iterator<Item = Result<T, E>>,
581    {
582        type Item = T;
583
584        #[inline]
585        fn next(&mut self) -> Option<Self::Item> {
586            match &mut self.state {
587                State::Active(inner) => match inner.next() {
588                    Some(Ok(t)) => Some(t),
589                    Some(Err(e)) => {
590                        self.state = State::FoundFirstErr(e);
591                        None
592                    }
593                    None => {
594                        self.state = State::Exhausted;
595                        None
596                    }
597                },
598                State::FoundFirstErr(_) => None,
599                State::Exhausted => None,
600            }
601        }
602
603        #[inline]
604        fn size_hint(&self) -> (usize, Option<usize>) {
605            match &self.state {
606                State::Active(inner) => inner.size_hint(),
607                State::FoundFirstErr(_) => (0, Some(0)),
608                State::Exhausted => (0, Some(0)),
609            }
610        }
611    }
612
613    impl<I, T, E> FusedIterator for FirstErrIter<I, T, E> where I: Iterator<Item = Result<T, E>> {}
614
615    /// Internal state of [`FirstErrIter`].
616    #[derive(Debug)]
617    enum State<I, T, E>
618    where
619        I: Iterator<Item = Result<T, E>>,
620    {
621        Active(I),
622        FoundFirstErr(E),
623        Exhausted,
624    }
625}
626
627mod option {
628    use core::iter::FusedIterator;
629
630    /// An `Iterator` can take first `None` from another iterator.
631    ///
632    /// See [`FirstErr::first_none_or_else()`](crate::FirstErr::first_none_or_else) for more details.
633    #[derive(Debug)]
634    pub struct FirstNoneIter<I, T>
635    where
636        I: Iterator<Item = Option<T>>,
637    {
638        state: State<I, T>,
639    }
640
641    impl<I, T> FirstNoneIter<I, T>
642    where
643        I: Iterator<Item = Option<T>>,
644    {
645        #[inline]
646        pub(super) fn first_none_or_else<O, F>(inner: I, f: F) -> Option<O>
647        where
648            F: FnOnce(&mut Self) -> O,
649        {
650            let mut me = Self {
651                state: State::Active(inner),
652            };
653
654            let output = f(&mut me);
655
656            // Take first None, if not found and not exhausted yet, find it.
657            // If just not found finally, return output.
658            match me.state {
659                State::Active(inner) => {
660                    for opt in inner {
661                        let _ = opt?;
662                    }
663                    Some(output)
664                }
665                State::Exhausted => Some(output),
666                State::FoundFirstNone => None,
667            }
668        }
669    }
670
671    impl<I, T> Iterator for FirstNoneIter<I, T>
672    where
673        I: Iterator<Item = Option<T>>,
674    {
675        type Item = T;
676
677        #[inline]
678        fn next(&mut self) -> Option<Self::Item> {
679            match &mut self.state {
680                State::Active(inner) => match inner.next() {
681                    Some(Some(t)) => Some(t),
682                    Some(None) => {
683                        self.state = State::FoundFirstNone;
684                        None
685                    }
686                    None => {
687                        self.state = State::Exhausted;
688                        None
689                    }
690                },
691                State::FoundFirstNone => None,
692                State::Exhausted => None,
693            }
694        }
695
696        #[inline]
697        fn size_hint(&self) -> (usize, Option<usize>) {
698            match &self.state {
699                State::Active(inner) => inner.size_hint(),
700                State::FoundFirstNone => (0, Some(0)),
701                State::Exhausted => (0, Some(0)),
702            }
703        }
704    }
705
706    impl<I, T> FusedIterator for FirstNoneIter<I, T> where I: Iterator<Item = Option<T>> {}
707
708    /// Internal state of [`FirstNoneIter`].
709    #[derive(Debug)]
710    enum State<I, T>
711    where
712        I: Iterator<Item = Option<T>>,
713    {
714        Active(I),
715        FoundFirstNone,
716        Exhausted,
717    }
718}
719
720#[cfg(test)]
721mod tests {
722    mod test_first_err {
723        //! Test first_err_* methods.
724
725        use crate::FirstErr;
726
727        #[test]
728        fn _or_else_with_1_layer_data_and_without_err() {
729            let ans = [Ok::<u8, u8>(0), Ok(1), Ok(2), Ok(3), Ok(4)]
730                .into_iter()
731                .first_err_or_else(|iter1| iter1.sum::<u8>());
732
733            assert_eq!(ans, Ok(10));
734        }
735
736        #[test]
737        fn _or_else_with_1_layer_data_and_with_err() {
738            let ans = [Ok::<u8, u8>(0), Ok(1), Err(2), Ok(3), Ok(4)]
739                .into_iter()
740                .first_err_or_else(|iter1| iter1.sum::<u8>());
741
742            assert_eq!(ans, Err(2));
743        }
744
745        #[test]
746        fn _or_else_with_2_layer_data_and_outmost_err_in_layer_1() {
747            let ans = [
748                Ok::<Result<u8, u8>, u8>(Ok(0)),
749                Ok(Err(1)),
750                Err(2),
751                Ok(Ok(3)),
752                Ok(Ok(4)),
753            ]
754            .into_iter()
755            .first_err_or_else(|iter1| {
756                iter1
757                    // could chain other ops
758                    .first_err_or_else(|iter2| iter2.sum::<u8>())
759            });
760
761            assert_eq!(ans, Err(2));
762        }
763
764        #[test]
765        fn _or_else_with_2_layer_data_and_outmost_err_in_layer_2() {
766            let ans = [
767                Ok::<Result<u8, u8>, u8>(Ok(0)),
768                Ok(Ok(1)),
769                Ok(Err(2)),
770                Ok(Err(3)),
771                Ok(Ok(4)),
772            ]
773            .into_iter()
774            .first_err_or_else(|iter1| {
775                iter1
776                    // could chain other ops
777                    .first_err_or_else(|iter2| iter2.sum::<u8>())
778            });
779
780            assert_eq!(ans, Ok(Err(2)));
781        }
782
783        #[test]
784        fn _or_else_with_3_layer_data_and_outmost_err_in_layer_2() {
785            let ans = [
786                Ok::<Result<Result<u8, u8>, u8>, u8>(Ok(Ok(0))),
787                Ok(Ok(Ok(1))),
788                Ok(Ok(Err(2))),
789                Ok(Err(3)),
790                Ok(Ok(Ok(4))),
791            ]
792            .into_iter()
793            .first_err_or_else(|iter1| {
794                iter1
795                    // could chain other ops
796                    .first_err_or_else(|iter2| {
797                        iter2
798                            // could chain other ops
799                            .first_err_or_else(|iter3| iter3.sum::<u8>())
800                    })
801            });
802
803            assert_eq!(ans, Ok(Err(3)));
804        }
805
806        #[test]
807        fn _or_else_not_need_to_consume_iter_manually() {
808            let ans = [Ok::<u8, u8>(0), Err(1), Err(2)]
809                .into_iter()
810                .first_err_or_else(|_iter| {});
811
812            assert_eq!(ans, Err(1));
813        }
814
815        /// In most cases, API users should not be concerned about how many times the original
816        /// iterator's `.next()` method is called, as it gets consumed after
817        /// `first_err_or_else()` is called.
818        ///
819        /// However, if the inner iterator has some side-effect, this behavior is still
820        /// observable, and users may rely on it.
821        ///
822        /// This test is designed to ensure that this behavior remains consistent even when
823        /// the code changes.
824        #[test]
825        fn _or_else_never_call_next_on_orig_iter_after_first_err_found() {
826            let mut orig_iter_next_count = 0;
827
828            [Ok::<u8, u8>(0), Err(1), Err(2)]
829                .into_iter()
830                .inspect(|_| orig_iter_next_count += 1) // side-effect
831                .first_err_or_else(|iter| {
832                    // exhaust whole iter.
833                    for _ in &mut *iter {}
834
835                    // call iter.next() after the iter already exhausted.
836                    assert_eq!(iter.next(), None);
837                })
838                .ok();
839
840            assert_eq!(orig_iter_next_count, 2);
841        }
842
843        #[test]
844        fn _or_else_use_lazy_evaluation() {
845            use core::cell::{Cell, RefCell};
846
847            #[derive(Debug, Clone, Copy, PartialEq, Eq)]
848            enum Trace {
849                None,
850                Outer(Result<u8, u8>),
851                Inner(u8),
852            }
853
854            // if index >= N, it will panic.
855            fn record_trace<const N: usize>(
856                traces: &RefCell<[Trace; N]>,
857                idx: &Cell<usize>,
858                v: Trace,
859            ) {
860                let i = idx.get();
861                traces.borrow_mut()[i] = v;
862                idx.set(i + 1);
863            }
864
865            // already known N = 5 within [_; N] in this test case.
866            // We don't use Vec here just bacause want to avoid `alloc` crate.
867            let traces = RefCell::new([Trace::None; 5]);
868
869            let index = Cell::new(0);
870
871            let ans = [Ok::<u8, u8>(0), Ok(1), Err(2), Ok(3)]
872                .iter()
873                .cloned()
874                // record value from outer
875                .inspect(|&res| record_trace(&traces, &index, Trace::Outer(res)))
876                .first_err_or_else(|iter| {
877                    iter
878                        // record value from inner
879                        .inspect(|&n| record_trace(&traces, &index, Trace::Inner(n)))
880                        .sum::<u8>()
881                });
882
883            assert_eq!(ans, Err(2));
884            assert_eq!(
885                traces.into_inner(),
886                [
887                    Trace::Outer(Ok(0)),
888                    Trace::Inner(0),
889                    Trace::Outer(Ok(1)),
890                    Trace::Inner(1),
891                    Trace::Outer(Err(2))
892                ]
893            );
894        }
895
896        #[test]
897        fn _or_else_with_non_fused_iterator() {
898            struct NonFusedIter {
899                curr: u32,
900            }
901
902            impl NonFusedIter {
903                fn new() -> Self {
904                    Self { curr: 0 }
905                }
906            }
907
908            impl Iterator for NonFusedIter {
909                type Item = Result<u32, u32>;
910
911                fn next(&mut self) -> Option<Self::Item> {
912                    let tmp = self.curr;
913                    self.curr += 1;
914
915                    match tmp % 3 {
916                        0 => Some(Ok(tmp)),
917                        1 => None,
918                        2 => Some(Err(tmp)),
919                        _ => unreachable!(),
920                    }
921                }
922            }
923
924            let ans = NonFusedIter::new().first_err_or_else(|iter| iter.sum::<u32>());
925
926            assert_eq!(ans, Ok(0));
927        }
928
929        #[test]
930        fn _or_without_err() {
931            let ans = [Ok::<u8, u8>(0), Ok(1), Ok(2), Ok(3), Ok(4)]
932                .into_iter()
933                .first_err_or("no err");
934
935            assert_eq!(ans, Ok("no err"));
936        }
937
938        #[test]
939        fn _or_with_err() {
940            let ans = [Ok::<u8, u8>(0), Ok(1), Err(2), Ok(3), Ok(4)]
941                .into_iter()
942                .first_err_or("no err");
943
944            assert_eq!(ans, Err(2));
945        }
946
947        #[test]
948        fn _or_try_without_err_and_closure_produce_ok() {
949            let ans = [Ok::<u8, u8>(0), Ok(1), Ok(2), Ok(3), Ok(4)]
950                .into_iter()
951                .first_err_or_try(|iter| iter.nth(1).ok_or(1));
952
953            assert_eq!(ans, Ok(1));
954        }
955
956        #[test]
957        fn _or_try_without_err_and_closure_produce_err() {
958            let ans = [Ok::<u8, u8>(0), Ok(1), Ok(2), Ok(3), Ok(4)]
959                .into_iter()
960                .first_err_or_try(|iter| iter.nth(100).ok_or(100));
961
962            assert_eq!(ans, Err(100));
963        }
964
965        #[test]
966        fn _or_try_with_err_and_closure_produce_ok() {
967            let ans = [Ok::<u8, u8>(0), Ok(1), Err(2), Ok(3), Ok(4)]
968                .into_iter()
969                .first_err_or_try(|iter| iter.nth(1).ok_or(1));
970
971            assert_eq!(ans, Err(2));
972        }
973
974        #[test]
975        fn _or_try_with_err_and_closure_produce_err() {
976            let ans = [Ok::<u8, u8>(0), Ok(1), Err(2), Ok(3), Ok(4)]
977                .into_iter()
978                .first_err_or_try(|iter| iter.nth(100).ok_or(100));
979
980            assert_eq!(ans, Err(2));
981        }
982
983        #[test]
984        fn _methods_can_call_through_trait_object() {
985            let mut array_iter = [Ok::<u8, u8>(0), Err(1), Err(2)].into_iter();
986
987            fn take_dyn(iter: &mut dyn Iterator<Item = Result<u8, u8>>) {
988                iter.first_err_or_else(|iter| iter.sum::<u8>()).ok();
989                iter.first_err_or(0).ok();
990                iter.first_err_or_try(|iter| Ok(iter.sum::<u8>())).ok();
991            }
992
993            take_dyn(&mut array_iter);
994        }
995    }
996
997    mod test_first_none {
998        //! Test first_none_* methods.
999
1000        use crate::FirstErr;
1001
1002        #[test]
1003        fn _or_else_with_1_layer_data_and_without_none() {
1004            let ans = [Some(0u8), Some(1), Some(2), Some(3), Some(4)]
1005                .into_iter()
1006                .first_none_or_else(|iter1| iter1.sum::<u8>());
1007
1008            assert_eq!(ans, Some(10));
1009        }
1010
1011        #[test]
1012        fn _or_else_with_1_layer_data_and_with_none() {
1013            let ans = [Some(0u8), Some(1), None, Some(3), Some(4)]
1014                .into_iter()
1015                .first_none_or_else(|iter1| iter1.sum::<u8>());
1016
1017            assert_eq!(ans, None);
1018        }
1019
1020        #[test]
1021        fn _or_else_with_2_layer_data_and_outmost_none_in_layer_1() {
1022            let ans = [
1023                Some(Some(0u8)),
1024                Some(None),
1025                None,
1026                Some(Some(3)),
1027                Some(Some(4)),
1028            ]
1029            .into_iter()
1030            .first_none_or_else(|iter1| {
1031                iter1
1032                    // could chain other ops
1033                    .first_none_or_else(|iter2| iter2.sum::<u8>())
1034            });
1035
1036            assert_eq!(ans, None);
1037        }
1038
1039        #[test]
1040        fn _or_else_with_2_layer_data_and_outmost_none_in_layer_2() {
1041            let ans = [
1042                Some(Some(0u8)),
1043                Some(Some(1)),
1044                Some(None),
1045                Some(Some(3)),
1046                Some(Some(4)),
1047            ]
1048            .into_iter()
1049            .first_none_or_else(|iter1| {
1050                iter1
1051                    // could chain other ops
1052                    .first_none_or_else(|iter2| iter2.sum::<u8>())
1053            });
1054
1055            assert_eq!(ans, Some(None));
1056        }
1057
1058        #[test]
1059        fn _or_else_with_3_layer_data_and_outmost_none_in_layer_2() {
1060            let ans = [
1061                Some(Some(Some(0))),
1062                Some(Some(Some(1))),
1063                Some(Some(None)),
1064                Some(None),
1065                Some(Some(Some(4))),
1066            ]
1067            .into_iter()
1068            .first_none_or_else(|iter1| {
1069                iter1
1070                    // could chain other ops
1071                    .first_none_or_else(|iter2| {
1072                        iter2
1073                            // could chain other ops
1074                            .first_none_or_else(|iter3| iter3.sum::<u8>())
1075                    })
1076            });
1077
1078            assert_eq!(ans, Some(None));
1079        }
1080
1081        #[test]
1082        fn _or_else_not_need_to_consume_iter_manually() {
1083            let ans = [Some(0), None, None]
1084                .into_iter()
1085                .first_none_or_else(|_iter| {});
1086
1087            assert_eq!(ans, None);
1088        }
1089
1090        /// In most cases, API users should not be concerned about how many times the original
1091        /// iterator's `.next()` method is called, as it gets consumed after
1092        /// `first_none_or_else()` is called.
1093        ///
1094        /// However, if the inner iterator has some side-effect, this behavior is still
1095        /// observable, and users may rely on it.
1096        ///
1097        /// This test is designed to ensure that this behavior remains consistent even when
1098        /// the code changes.
1099        #[test]
1100        fn _or_else_never_call_next_on_orig_iter_after_first_none_found() {
1101            let mut orig_iter_next_count = 0;
1102
1103            [Some(0), None, None]
1104                .into_iter()
1105                .inspect(|_| orig_iter_next_count += 1) // side-effect
1106                .first_none_or_else(|iter| {
1107                    // exhaust whole iter.
1108                    for _ in &mut *iter {}
1109
1110                    // call iter.next() after the iter already exhausted.
1111                    assert_eq!(iter.next(), None);
1112                });
1113
1114            assert_eq!(orig_iter_next_count, 2);
1115        }
1116
1117        #[test]
1118        fn _or_else_use_lazy_evaluation() {
1119            use core::cell::{Cell, RefCell};
1120
1121            #[derive(Debug, Clone, Copy, PartialEq, Eq)]
1122            enum Trace {
1123                None,
1124                Outer(Option<u8>),
1125                Inner(u8),
1126            }
1127
1128            // if index >= N, it will panic.
1129            fn record_trace<const N: usize>(
1130                traces: &RefCell<[Trace; N]>,
1131                idx: &Cell<usize>,
1132                v: Trace,
1133            ) {
1134                let i = idx.get();
1135                traces.borrow_mut()[i] = v;
1136                idx.set(i + 1);
1137            }
1138
1139            // already known N = 5 within [_; N] in this test case.
1140            // We don't use Vec here just bacause want to avoid `alloc` crate.
1141            let traces = RefCell::new([Trace::None; 5]);
1142
1143            let index = Cell::new(0);
1144
1145            let ans = [Some(0u8), Some(1), None, Some(3)]
1146                .iter()
1147                .cloned()
1148                // record value from outer
1149                .inspect(|&opt| record_trace(&traces, &index, Trace::Outer(opt)))
1150                .first_none_or_else(|iter| {
1151                    iter
1152                        // record value from inner
1153                        .inspect(|&n| record_trace(&traces, &index, Trace::Inner(n)))
1154                        .sum::<u8>()
1155                });
1156
1157            assert_eq!(ans, None);
1158            assert_eq!(
1159                traces.into_inner(),
1160                [
1161                    Trace::Outer(Some(0)),
1162                    Trace::Inner(0),
1163                    Trace::Outer(Some(1)),
1164                    Trace::Inner(1),
1165                    Trace::Outer(None)
1166                ]
1167            );
1168        }
1169
1170        #[test]
1171        fn _or_else_with_non_fused_iterator() {
1172            struct NonFusedIter {
1173                curr: u32,
1174            }
1175
1176            impl NonFusedIter {
1177                fn new() -> Self {
1178                    Self { curr: 0 }
1179                }
1180            }
1181
1182            impl Iterator for NonFusedIter {
1183                type Item = Option<u32>;
1184
1185                fn next(&mut self) -> Option<Self::Item> {
1186                    let tmp = self.curr;
1187                    self.curr += 1;
1188
1189                    match tmp % 3 {
1190                        0 => Some(Some(tmp)),
1191                        1 => None,       // after produce a None ...
1192                        2 => Some(None), // it still can produce Some(value)
1193                        _ => unreachable!(),
1194                    }
1195                }
1196            }
1197
1198            let ans = NonFusedIter::new().first_none_or_else(|iter| iter.sum::<u32>());
1199
1200            assert_eq!(ans, Some(0));
1201        }
1202
1203        #[test]
1204        fn _or_without_none() {
1205            let ans = [Some(0u8), Some(1), Some(2), Some(3), Some(4)]
1206                .into_iter()
1207                .first_none_or("no none");
1208
1209            assert_eq!(ans, Some("no none"));
1210        }
1211
1212        #[test]
1213        fn _or_with_none() {
1214            let ans = [Some(0u8), Some(1), None, Some(3), Some(4)]
1215                .into_iter()
1216                .first_none_or("no none");
1217
1218            assert_eq!(ans, None);
1219        }
1220
1221        #[test]
1222        fn _or_try_without_none_and_closure_produce_some() {
1223            let ans = [Some(0u8), Some(1), Some(2), Some(3), Some(4)]
1224                .into_iter()
1225                .first_none_or_try(|iter| iter.nth(1));
1226
1227            assert_eq!(ans, Some(1));
1228        }
1229
1230        #[test]
1231        fn _or_try_without_none_and_closure_produce_none() {
1232            let ans = [Some(0u8), Some(1), Some(2), Some(3), Some(4)]
1233                .into_iter()
1234                .first_none_or_try(|iter| iter.nth(100));
1235
1236            assert_eq!(ans, None);
1237        }
1238
1239        #[test]
1240        fn _or_try_with_none_and_closure_produce_some() {
1241            let ans = [Some(0u8), Some(1), None, Some(3), Some(4)]
1242                .into_iter()
1243                .first_none_or_try(|iter| iter.nth(1));
1244
1245            assert_eq!(ans, None);
1246        }
1247
1248        #[test]
1249        fn _or_try_with_none_and_closure_produce_none() {
1250            let ans = [Some(0u8), Some(1), None, Some(3), Some(4)]
1251                .into_iter()
1252                .first_none_or_try(|iter| iter.nth(100));
1253
1254            assert_eq!(ans, None);
1255        }
1256
1257        #[test]
1258        fn _methods_can_call_through_trait_object() {
1259            let mut array_iter = [Some(0u8), None, None].into_iter();
1260
1261            fn take_dyn(iter: &mut dyn Iterator<Item = Option<u8>>) {
1262                iter.first_none_or_else(|iter| iter.sum::<u8>());
1263                iter.first_none_or(0);
1264                iter.first_none_or_try(|iter| Some(iter.sum::<u8>()));
1265            }
1266
1267            take_dyn(&mut array_iter);
1268        }
1269    }
1270}