orx_iterable/transformations/
skipped_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 skips the elements
6/// of the original iterable that satisfy a given predicate and yields the
7/// remaining.
8pub struct SkippedWhile<I, P>
9where
10    I: Iterable,
11    P: Fn(&I::Item) -> bool + Copy,
12{
13    pub(crate) it: I,
14    pub(crate) skip_while: P,
15}
16
17impl<I, P> Iterable for SkippedWhile<I, P>
18where
19    I: Iterable,
20    P: Fn(&I::Item) -> bool + Copy,
21{
22    type Item = I::Item;
23
24    type Iter = core::iter::SkipWhile<I::Iter, P>;
25
26    fn iter(&self) -> Self::Iter {
27        self.it.iter().skip_while(self.skip_while)
28    }
29}
30
31// col
32
33/// Wraps an `Collection` and creates a new `Collection` which skips the elements
34/// of the original iterable that satisfy a given predicate and yields the
35/// remaining.
36pub struct SkippedWhileCol<I, E, P>
37where
38    I: Collection,
39    E: SoM<I>,
40    P: Fn(&I::Item) -> bool + Copy,
41{
42    pub(crate) it: E,
43    pub(crate) skip_while: P,
44    pub(crate) phantom: PhantomData<I>,
45}
46
47impl<'a, I, E, P> Iterable for &'a SkippedWhileCol<I, E, P>
48where
49    I: Collection,
50    E: SoM<I>,
51    P: Fn(&I::Item) -> bool + Copy,
52{
53    type Item = &'a I::Item;
54
55    type Iter = SkippedWhileColIter<'a, I, P>;
56
57    fn iter(&self) -> Self::Iter {
58        let iter = self.it.get_ref().iter();
59        SkippedWhileColIter {
60            iter,
61            skip_while: self.skip_while,
62            skipped: false,
63        }
64    }
65}
66
67impl<I, E, P> Collection for SkippedWhileCol<I, E, P>
68where
69    I: Collection,
70    E: SoM<I>,
71    P: Fn(&I::Item) -> bool + Copy,
72{
73    type Item = I::Item;
74
75    type Iterable<'i>
76        = &'i Self
77    where
78        Self: 'i;
79
80    fn as_iterable(&self) -> Self::Iterable<'_> {
81        self
82    }
83}
84
85impl<I, E, P> CollectionMut for SkippedWhileCol<I, E, P>
86where
87    I: CollectionMut,
88    E: SoM<I>,
89    P: Fn(&I::Item) -> bool + Copy,
90{
91    type IterMut<'i>
92        = SkippedWhileColIterMut<'i, I, P>
93    where
94        Self: 'i;
95
96    fn iter_mut(&mut self) -> Self::IterMut<'_> {
97        let iter = self.it.get_mut().iter_mut();
98        SkippedWhileColIterMut {
99            iter,
100            skip_while: self.skip_while,
101            skipped: false,
102        }
103    }
104}
105
106// col - iters
107
108/// Immutable iterator for skipped while iterable collection.
109pub struct SkippedWhileColIter<'a, I, P>
110where
111    I: Collection + 'a,
112    P: Fn(&I::Item) -> bool + Copy,
113{
114    pub(crate) iter: <I::Iterable<'a> as Iterable>::Iter,
115    pub(crate) skip_while: P,
116    pub(crate) skipped: bool,
117}
118
119impl<'a, I, P> Iterator for SkippedWhileColIter<'a, I, P>
120where
121    I: Collection,
122    P: Fn(&I::Item) -> bool + Copy,
123{
124    type Item = <I::Iterable<'a> as Iterable>::Item;
125
126    fn next(&mut self) -> Option<Self::Item> {
127        match self.skipped {
128            true => self.iter.next(),
129            false => loop {
130                match self.iter.next() {
131                    Some(x) => match (self.skip_while)(x) {
132                        true => {}
133                        false => {
134                            self.skipped = true;
135                            return Some(x);
136                        }
137                    },
138                    None => {
139                        self.skipped = true;
140                        return None;
141                    }
142                }
143            },
144        }
145    }
146}
147
148/// Mutable iterator for skipped while iterable collection.
149pub struct SkippedWhileColIterMut<'a, I, P>
150where
151    I: CollectionMut + 'a,
152    P: Fn(&I::Item) -> bool + Copy,
153{
154    pub(crate) iter: I::IterMut<'a>,
155    pub(crate) skip_while: P,
156    pub(crate) skipped: bool,
157}
158
159impl<'a, I, P> Iterator for SkippedWhileColIterMut<'a, I, P>
160where
161    I: CollectionMut,
162    P: Fn(&I::Item) -> bool + Copy,
163{
164    type Item = <I::IterMut<'a> as Iterator>::Item;
165
166    fn next(&mut self) -> Option<Self::Item> {
167        match self.skipped {
168            true => self.iter.next(),
169            false => loop {
170                match self.iter.next() {
171                    Some(x) => match (self.skip_while)(x) {
172                        true => {}
173                        false => {
174                            self.skipped = true;
175                            return Some(x);
176                        }
177                    },
178                    None => {
179                        self.skipped = true;
180                        return None;
181                    }
182                }
183            },
184        }
185    }
186}