1use core::iter::{from_fn, once};
2
3use crate::common::either::Either;
4
5pub trait Iter: Sized + Iterator {
6 fn intersperse_(self, sep: Self::Item) -> impl Iterator<Item = Self::Item>
8 where
9 Self::Item: Clone,
10 {
11 self.flat_map(move |x| [sep.clone(), x]).skip(1)
12 }
13
14 fn try_flatten<I: IntoIterator, E>(self) -> impl Iterator<Item = Result<I::Item, E>>
16 where
17 Self: Iterator<Item = Result<I, E>>,
18 {
19 self.flat_map(|v| match v {
20 Err(e) => Either::Left(once(Err(e))),
21 Ok(i) => Either::Right(i.into_iter().map(Result::Ok)),
22 })
23 }
24
25 fn zip_longest<J: IntoIterator>(
29 self,
30 j: J,
31 ) -> impl Iterator<Item = (Option<Self::Item>, Option<J::Item>)> {
32 let mut i = self.fuse();
33 let mut j = j.into_iter().fuse();
34 from_fn(move || match (i.next(), j.next()) {
35 (None, None) => None,
36 pair => Some(pair),
37 })
38 }
39
40 fn eq_by_<J: Iterator>(self, j: J, mut cmp: impl FnMut(&Self::Item, &J::Item) -> bool) -> bool {
42 self.zip_longest(j).all(|pair| match pair {
43 (Some(x), Some(y)) => cmp(&x, &y),
44 _ => false,
45 })
46 }
47}
48
49impl<T: Sized + Iterator> Iter for T {}
50
51#[cfg(test)]
52mod test {
53 use super::Iter;
54
55 #[test]
56 fn zip_longest_same_length() {
57 let pairs: Vec<_> = [1, 2].into_iter().zip_longest(['a', 'b']).collect();
58 assert_eq!(pairs, [(Some(1), Some('a')), (Some(2), Some('b'))]);
59 }
60
61 #[test]
62 fn zip_longest_left_longer() {
63 let pairs: Vec<_> = [1, 2].into_iter().zip_longest(['a']).collect();
64 assert_eq!(pairs, [(Some(1), Some('a')), (Some(2), None)]);
65 }
66
67 #[test]
68 fn zip_longest_right_longer() {
69 let pairs: Vec<_> = [1].into_iter().zip_longest(['a', 'b']).collect();
70 assert_eq!(pairs, [(Some(1), Some('a')), (None, Some('b'))]);
71 }
72
73 #[test]
74 fn zip_longest_empty() {
75 let pairs: Vec<_> = [0; 0].into_iter().zip_longest(['a'; 0]).collect();
76 assert_eq!(pairs, []);
77 }
78
79 #[test]
80 fn eq_by_() {
81 let eq = |a: &i32, b: &i32| a == b;
82 assert!([1, 2].into_iter().eq_by_([1, 2].into_iter(), eq));
83 assert!(![1, 2].into_iter().eq_by_([1, 3].into_iter(), eq));
84 assert!(![1, 2].into_iter().eq_by_([1].into_iter(), eq));
85 assert!(![1].into_iter().eq_by_([1, 2].into_iter(), eq));
86 assert!([].into_iter().eq_by_([].into_iter(), eq));
87 }
88}