more_itertools/augmenting/
intersperse.rs

1use std::collections::VecDeque;
2
3use crate::error;
4use crate::error::Error;
5
6struct IntersperseOutputBuffer<T> 
7{
8    items: VecDeque<T>
9}
10
11pub struct Intersperse<T> 
12where
13T: Clone + 'static
14{
15    buffer: IntersperseOutputBuffer<T>,
16    iter: Box<dyn Iterator<Item=Result<T,Error>>>,
17    n: usize,
18    e: T,
19    iter_finished: bool,
20    emit_count: usize,
21}
22
23impl<T> Iterator for Intersperse<T>
24where
25T: Clone
26{
27    type Item = Result<T, Error>;
28
29    fn next(&mut self) -> Option<Self::Item> {
30        if self.iter_finished {
31            return None;
32        }
33
34        if self.n == 0 {
35            return Some(Err(error::value_error("[intersperse:n must be > 0]".to_string())));
36        }
37
38        loop {
39            if self.buffer.items.len() > 0 {
40                if self.emit_count == self.n {
41                    self.emit_count = 0;
42                    return Some(Ok(self.e.clone()));
43                }
44                let ret = self.buffer.items.pop_front().unwrap();
45                self.emit_count += 1;
46                return Some(Ok(ret));
47            } else {
48                let _next = self.iter.next();
49                match _next {
50                    None => { 
51                        self.iter_finished = true;
52                        return None; 
53                    }
54                    Some(v) => { 
55                        match v {
56                            Ok(ok_v) => {
57                                self.buffer.items.push_back(ok_v);
58                            },
59                            Err(err_v) => { // upstream error
60                                self.iter_finished = true;
61                                return Some(Err(err_v));
62                            }
63                        }
64                    }
65                }
66            }
67        }
68    }
69}
70
71pub fn intersperse<T>(e: T, iter: Box<dyn Iterator<Item=Result<T,Error>>>, n: usize) -> Box<dyn Iterator<Item=Result<T, Error>>>
72where
73T: Clone + 'static
74{
75    let isp = Intersperse {
76        buffer: IntersperseOutputBuffer {
77            items: VecDeque::new(),
78        },
79        iter,
80        n,
81        e,
82        iter_finished: false,
83        emit_count: 0
84    };
85
86    return Box::new(isp);
87}
88
89#[cfg(test)]
90mod tests {
91    use crate::utils::{extract_value_from_result_vec, generate_okok_iterator, generate_okokerr_iterator};
92
93    use super::*;
94
95    #[test]
96    fn test1() {
97        let mut isp = intersperse(0, generate_okok_iterator(vec![1,2,3,4,5]), 0);
98        assert_eq!(error::Kind::ValueError, isp.next().unwrap().err().unwrap().kind());
99
100        let mut isp = intersperse(0, generate_okok_iterator(Vec::<i32>::new()), 1);
101        assert_eq!(None, isp.next());
102
103        let isp = intersperse(0, generate_okok_iterator(vec![1,2,3,4,5]), 1);
104        assert_eq!((vec![1, 0, 2, 0, 3, 0, 4, 0, 5], None), extract_value_from_result_vec(isp.collect::<Vec<_>>()));
105
106        let isp = intersperse(0, generate_okok_iterator(vec![1,2,3,4,5]), 2);
107        assert_eq!((vec![1, 2, 0, 3, 4, 0, 5], None), extract_value_from_result_vec(isp.collect::<Vec<_>>()));
108
109        let isp = intersperse(0, generate_okok_iterator(vec![1]), 1);
110        assert_eq!((vec![1], None), extract_value_from_result_vec(isp.collect::<Vec<_>>()));
111
112        let isp = intersperse(0, generate_okok_iterator(vec![1]), 2);
113        assert_eq!((vec![1], None), extract_value_from_result_vec(isp.collect::<Vec<_>>()));
114
115
116        
117        let mut isp = intersperse(0, generate_okokerr_iterator(vec![1,2,3,4,5], error::overflow_error("[test]".to_string())), 2);
118        assert_eq!(1, isp.next().unwrap().ok().unwrap());
119        assert_eq!(2, isp.next().unwrap().ok().unwrap());
120        assert_eq!(0, isp.next().unwrap().ok().unwrap());
121        assert_eq!(3, isp.next().unwrap().ok().unwrap());
122        assert_eq!(4, isp.next().unwrap().ok().unwrap());
123        assert_eq!(0, isp.next().unwrap().ok().unwrap());
124        assert_eq!(5, isp.next().unwrap().ok().unwrap());
125        assert_eq!(error::Kind::OverflowError, isp.next().unwrap().err().unwrap().kind());
126        assert_eq!(None, isp.next());
127        
128    }
129}