more_itertools/itertools/
sum.rs1
2
3#[macro_export]
4macro_rules! sum {
5 ($arg:ty, $iter:expr, $init:expr) => {
6 {
7 let mut overflow = false;
8 let mut upstream_error = false;
9 let mut the_upstream_error = Err(error::any_error(error::Kind::None, "none error".to_string()));
10 let mut sum0: $arg = $init;
11
12 let mut _next = $iter.next();
13 while !_next.is_none() {
14 match _next {
15 None=>{
16 break;
17 }
18 Some(v) => {
19 if !v.is_ok() {
20 upstream_error = true;
21 the_upstream_error = v;
22 break;
23 } else {
24 let add_result = <$arg>::overflowing_add(sum0, v.ok().unwrap());
25
26 if add_result.1 {
27 overflow = true;
28 break;
29 } else {
30 sum0 = add_result.0;
31 _next = $iter.next();
32 continue;
33 }
34 }
35 }
36 }
37 }
38
39 if upstream_error {
40 the_upstream_error
41 } else if overflow {
42 Err(error::any_error(error::Kind::OverflowError, "Add overflow.".to_string()))
43 } else {
44 Ok(sum0)
45 }
46 }
47 };
48}
49
50pub(crate) use sum;
51
52
53#[cfg(test)]
54mod tests {
55 use crate::error;
56 use crate::itertools::iter::iter_from_vec;
57 use crate::itertools::map::map2;
58 use crate::utils::generate_okok_iterator;
59
60 #[test]
63 fn test1() {
64 let v = vec![Ok(1usize),Ok(2),Ok(3)];
65 let mut iter: Box<dyn Iterator<Item = Result<usize, error::Error>>> = iter_from_vec(v);
66 let ret = sum!(usize, iter, 0);
67 assert_eq!(Ok(6), ret);
68
69 let v = Vec::<Result<usize,error::Error>>::new();
70 let mut iter = iter_from_vec(v);
71 let ret = sum!(usize, iter, 0);
72 assert_eq!(Ok(0), ret);
73
74 let v = vec![Ok(usize::MAX),Ok(2),Ok(3)];
75 let mut iter = iter_from_vec(v);
76 let ret = sum!(usize, iter, 0);
77 assert_eq!(error::Kind::OverflowError, ret.err().unwrap().kind());
78
79 let v1 = generate_okok_iterator(vec![2, 3, usize::MAX]);
80 let v2 = generate_okok_iterator(vec![1, 2, 3]);
81 let mut iter = map2(v1, v2, |x, y| {
82 let ret = x.overflowing_mul(*y);
83 if ret.1 {
84 return Err(error::any_error(error::Kind::OverflowError, "multiple overflow.".to_string()));
85 } else {
86 return Ok(ret.0);
87 }
88 });
89 let ret = sum!(usize, iter, 0);
90 assert!(ret.is_err());
91 assert!(ret.err().unwrap().message().unwrap().contains("multiple overflow"));
92
93 }
94}