orx_iterable/transformations/
taken_while.rs

1use crate::{Collection, CollectionMut, Iterable};
2use core::marker::PhantomData;
3use orx_self_or::SoM;
4
5/// Wraps an `Iterable` and creates a new `Iterable` which yields elements of
6/// the original iterable as long as a predicate is satisfied.
7pub struct TakenWhile<I, P>
8where
9    I: Iterable,
10    P: Fn(&I::Item) -> bool + Copy,
11{
12    pub(crate) it: I,
13    pub(crate) take_while: P,
14}
15
16impl<I, P> Iterable for TakenWhile<I, P>
17where
18    I: Iterable,
19    P: Fn(&I::Item) -> bool + Copy,
20{
21    type Item = I::Item;
22
23    type Iter = core::iter::TakeWhile<I::Iter, P>;
24
25    fn iter(&self) -> Self::Iter {
26        self.it.iter().take_while(self.take_while)
27    }
28}
29
30// col
31
32/// Wraps an `Collection` and creates a new `Collection` which yields elements of
33/// the original iterable as long as a predicate is satisfied.
34pub struct TakenWhileCol<I, E, P>
35where
36    I: Collection,
37    E: SoM<I>,
38    P: Fn(&I::Item) -> bool + Copy,
39{
40    pub(crate) it: E,
41    pub(crate) take_while: P,
42    pub(crate) phantom: PhantomData<I>,
43}
44
45impl<'a, I, E, P> Iterable for &'a TakenWhileCol<I, E, P>
46where
47    I: Collection,
48    E: SoM<I>,
49    P: Fn(&I::Item) -> bool + Copy,
50{
51    type Item = &'a I::Item;
52
53    type Iter = TakenWhileColIter<'a, I, P>;
54
55    fn iter(&self) -> Self::Iter {
56        let iter = self.it.get_ref().iter();
57        TakenWhileColIter {
58            iter,
59            filter: self.take_while,
60        }
61    }
62}
63
64impl<I, E, P> Collection for TakenWhileCol<I, E, P>
65where
66    I: Collection,
67    E: SoM<I>,
68    P: Fn(&I::Item) -> bool + Copy,
69{
70    type Item = I::Item;
71
72    type Iterable<'i>
73        = &'i Self
74    where
75        Self: 'i;
76
77    fn as_iterable(&self) -> Self::Iterable<'_> {
78        self
79    }
80}
81
82impl<I, E, P> CollectionMut for TakenWhileCol<I, E, P>
83where
84    I: CollectionMut,
85    E: SoM<I>,
86    P: Fn(&I::Item) -> bool + Copy,
87{
88    type IterMut<'i>
89        = TakenWhileColIterMut<'i, I, P>
90    where
91        Self: 'i;
92
93    fn iter_mut(&mut self) -> Self::IterMut<'_> {
94        let iter = self.it.get_mut().iter_mut();
95        TakenWhileColIterMut {
96            iter,
97            filter: self.take_while,
98        }
99    }
100}
101
102// col - iters
103
104/// Immutable iterator for taken while iterable collections.
105pub struct TakenWhileColIter<'a, I, P>
106where
107    I: Collection + 'a,
108    P: Fn(&I::Item) -> bool + Copy,
109{
110    pub(crate) iter: <I::Iterable<'a> as Iterable>::Iter,
111    pub(crate) filter: P,
112}
113
114impl<'a, I, P> Iterator for TakenWhileColIter<'a, I, P>
115where
116    I: Collection,
117    P: Fn(&I::Item) -> bool + Copy,
118{
119    type Item = <I::Iterable<'a> as Iterable>::Item;
120
121    fn next(&mut self) -> Option<Self::Item> {
122        let x = self.iter.next()?;
123        (self.filter)(x).then_some(x)
124    }
125}
126
127/// Mutable iterator for taken while iterable collections.
128pub struct TakenWhileColIterMut<'a, I, P>
129where
130    I: CollectionMut + 'a,
131    P: Fn(&I::Item) -> bool + Copy,
132{
133    pub(crate) iter: I::IterMut<'a>,
134    pub(crate) filter: P,
135}
136
137impl<'a, I, P> Iterator for TakenWhileColIterMut<'a, I, P>
138where
139    I: CollectionMut,
140    P: Fn(&I::Item) -> bool + Copy,
141{
142    type Item = <I::IterMut<'a> as Iterator>::Item;
143
144    fn next(&mut self) -> Option<Self::Item> {
145        let x = self.iter.next()?;
146        (self.filter)(x).then_some(x)
147    }
148}