downsample/
aggregatable.rs1use core::marker::ConstParamTy;
2
3#[derive(PartialEq, Eq, Debug, Clone, ConstParamTy)]
4pub enum Algorithm {
5 Average,
6 Min,
7 Max,
8}
9
10pub trait Aggregatable<const M: Algorithm> {
11 fn aggregate<I: Iterator<Item = Self>>(list: I) -> Self;
12}
13
14#[cfg(feature = "derive_aggregatable")]
15mod int {
16 use super::*;
17
18 macro_rules! impl_by_into {
19 ( $t:ty ) => {
20 impl Aggregatable<{ Algorithm::Average }> for $t {
21 fn aggregate<I: Iterator<Item = Self>>(list: I) -> Self {
22 let mut total = <$t>::default();
23 let mut count = 0;
24 for e in list {
25 total += e;
26 count += 1;
27 }
28 total / count as $t
29 }
30 }
31
32 impl Aggregatable<{ Algorithm::Min }> for $t {
33 fn aggregate<I: Iterator<Item = Self>>(list: I) -> Self {
34 let mut min = None;
35 for e in list {
36 if min.map(|m| e < m).unwrap_or(true) {
37 min = Some(e);
38 }
39 }
40 min.unwrap_or_default()
41 }
42 }
43
44 impl Aggregatable<{ Algorithm::Max }> for $t {
45 fn aggregate<I: Iterator<Item = Self>>(list: I) -> Self {
46 let mut max = None;
47 for e in list {
48 if max.map(|m| e > m).unwrap_or(true) {
49 max = Some(e);
50 }
51 }
52 max.unwrap_or_default()
53 }
54 }
55 };
56 }
57
58 impl_by_into!(f32);
59 impl_by_into!(f64);
60 impl_by_into!(u8);
61 impl_by_into!(u16);
62 impl_by_into!(u32);
63 impl_by_into!(u64);
64 impl_by_into!(u128);
65 impl_by_into!(i8);
66 impl_by_into!(i16);
67 impl_by_into!(i32);
68 impl_by_into!(i64);
69 impl_by_into!(i128);
70 impl_by_into!(usize);
71 impl_by_into!(isize);
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77 use crate::Algorithm;
78
79 #[test]
80 fn average_f32() {
81 assert_eq!(
82 Aggregatable::<{ Algorithm::Average }>::aggregate((0..10).map(|x| x as f32)),
83 4.5
84 )
85 }
86
87 #[test]
88 fn min_f32() {
89 assert_eq!(
90 Aggregatable::<{ Algorithm::Min }>::aggregate((-10..10).map(|x| x as f32)),
91 -10.0
92 )
93 }
94
95 #[test]
96 fn max_f32() {
97 assert_eq!(
98 Aggregatable::<{ Algorithm::Max }>::aggregate((-10..10).map(|x| x as f32)),
99 9.0
100 )
101 }
102}