more_itertools/augmenting/
mark_ends.rs

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