1use std::iter::Sum;
7
8pub trait Combiner<R>: Send + Sync {
10 type Output;
13
14 fn combine(&self, iter: impl Iterator<Item=R>) -> Self::Output;
21}
22
23#[derive(Default)]
24pub struct DefaultCombiner {}
27
28impl<R> Combiner<R> for DefaultCombiner {
29 type Output = Option<R>;
30
31 fn combine(&self, iter: impl Iterator<Item=R>) -> Option<R> {
32 iter.last()
33 }
34}
35
36#[derive(Default)]
37pub struct VecCombiner {}
39
40impl<R> Combiner<R> for VecCombiner {
41 type Output = Vec<R>;
42
43 fn combine(&self, iter: impl Iterator<Item=R>) -> Vec<R> {
44 iter.collect()
45 }
46}
47
48#[derive(Default)]
49pub struct SumCombiner {}
51
52impl<R> Combiner<R> for SumCombiner
53where
54 R: Sum
55{
56 type Output = R;
57
58 fn combine(&self, iter: impl Iterator<Item=R>) -> R {
59 iter.sum()
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66
67 #[test]
68 fn default_combiner_test() {
69 let combiner = DefaultCombiner::default();
70 let values1 = vec!(5, 1, 9);
71 let values2: Vec<i32> = Vec::new();
72 assert_eq!(combiner.combine(values1.into_iter()), Some(9));
73 assert_eq!(combiner.combine(values2.into_iter()), None);
74 }
75
76 #[test]
77 fn vec_combiner_test() {
78 let combiner = VecCombiner::default();
79 let values1 = vec!(5, 1, 9);
80 let values2: Vec<i32> = Vec::new();
81 assert_eq!(combiner.combine(values1.iter().cloned()), values1);
82 assert_eq!(combiner.combine(values2.iter().cloned()), values2);
83 }
84
85 #[test]
86 fn sum_combiner_test() {
87 let combiner = SumCombiner::default();
88 let values1 = vec!(5, 1, 9);
89 let values2: Vec<i32> = Vec::new();
90 assert_eq!(combiner.combine(values1.iter().cloned()), 15);
91 assert_eq!(combiner.combine(values2.iter().cloned()), 0);
92 }
93}