more_itertools/augmenting/
mark_ends.rs1use 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(); 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 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 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}