fluent_iterable/ops/
fallback.rs1#[derive(Debug)]
5pub struct WhenEmpty<I, F>
6where
7 I: Iterator,
8 F: IntoIterator<Item = I::Item>,
9{
10 pub(crate) phase: WhenEmptyPhase<I, F::IntoIter>,
11 pub(crate) fallback: Option<F>,
12}
13
14#[derive(Debug)]
15pub(crate) enum WhenEmptyPhase<S, T> {
16 Source(S, bool),
18 Fallback(T),
20 Done,
22}
23
24impl<I, F> Iterator for WhenEmpty<I, F>
25where
26 I: Iterator,
27 F: IntoIterator<Item = I::Item>,
28{
29 type Item = I::Item;
30
31 fn next(&mut self) -> Option<I::Item> {
32 match &mut self.phase {
33 WhenEmptyPhase::Source(source, yielded) => match source.next() {
34 Some(item) => {
35 *yielded = true;
36 Some(item)
37 }
38 None => {
39 if *yielded {
40 self.phase = WhenEmptyPhase::Done;
41 return None;
42 }
43 match self.fallback.take() {
44 Some(fallback) => {
45 let mut iter = fallback.into_iter();
46 let item = iter.next();
47 self.phase = WhenEmptyPhase::Fallback(iter);
48 item
49 }
50 None => {
51 self.phase = WhenEmptyPhase::Done;
52 None
53 }
54 }
55 }
56 },
57 WhenEmptyPhase::Fallback(iter) => iter.next(),
58 WhenEmptyPhase::Done => None,
59 }
60 }
61}
62#[derive(Debug)]
67pub struct Repeat<I: Iterator>
68where
69 I::Item: Clone,
70{
71 pub(crate) source: I,
72 pub(crate) cache: Vec<I::Item>,
73 pub(crate) times: usize,
74 pub(crate) round: usize,
76 pub(crate) pos: usize,
77}
78
79impl<I> Iterator for Repeat<I>
80where
81 I: Iterator,
82 I::Item: Clone,
83{
84 type Item = I::Item;
85
86 fn next(&mut self) -> Option<I::Item> {
87 if self.times == 0 {
88 return None;
89 }
90 loop {
91 if self.round == 0 {
92 if let Some(item) = self.source.next() {
93 self.cache.push(item.clone());
94 return Some(item);
95 }
96 self.round = 1;
97 self.pos = 0;
98 }
99 if self.round >= self.times {
100 return None;
101 }
102 if let Some(item) = self.cache.get(self.pos) {
103 self.pos += 1;
104 return Some(item.clone());
105 }
106 self.round += 1;
107 self.pos = 0;
108 }
109 }
110}