ferroui_dynamic_data/aggregation/
aggregate_number.rs1use std::fmt::Debug;
15
16pub trait AggregateNumber: Copy + PartialEq + PartialOrd + Debug + 'static {
18 type Average: Copy + PartialEq + PartialOrd + Debug + 'static;
21
22 const ZERO: Self;
24
25 fn plus(self, other: Self) -> Self;
27
28 fn minus(self, other: Self) -> Self;
30
31 fn average(sum: Self, count: i32) -> Self::Average;
34
35 fn to_average(self) -> Self::Average;
37}
38
39impl AggregateNumber for i32 {
40 type Average = f64;
41 const ZERO: i32 = 0;
42
43 fn plus(self, other: i32) -> i32 {
44 self.wrapping_add(other)
45 }
46
47 fn minus(self, other: i32) -> i32 {
48 self.wrapping_sub(other)
49 }
50
51 fn average(sum: i32, count: i32) -> f64 {
52 f64::from(sum) / f64::from(count)
53 }
54
55 fn to_average(self) -> f64 {
56 f64::from(self)
57 }
58}
59
60impl AggregateNumber for i64 {
61 type Average = f64;
62 const ZERO: i64 = 0;
63
64 fn plus(self, other: i64) -> i64 {
65 self.wrapping_add(other)
66 }
67
68 fn minus(self, other: i64) -> i64 {
69 self.wrapping_sub(other)
70 }
71
72 fn average(sum: i64, count: i32) -> f64 {
73 sum as f64 / f64::from(count)
74 }
75
76 fn to_average(self) -> f64 {
77 self as f64
78 }
79}
80
81impl AggregateNumber for f32 {
82 type Average = f32;
83 const ZERO: f32 = 0.0;
84
85 fn plus(self, other: f32) -> f32 {
86 self + other
87 }
88
89 fn minus(self, other: f32) -> f32 {
90 self - other
91 }
92
93 fn average(sum: f32, count: i32) -> f32 {
94 sum / count as f32
95 }
96
97 fn to_average(self) -> f32 {
98 self
99 }
100}
101
102impl AggregateNumber for f64 {
103 type Average = f64;
104 const ZERO: f64 = 0.0;
105
106 fn plus(self, other: f64) -> f64 {
107 self + other
108 }
109
110 fn minus(self, other: f64) -> f64 {
111 self - other
112 }
113
114 fn average(sum: f64, count: i32) -> f64 {
115 sum / f64::from(count)
116 }
117
118 fn to_average(self) -> f64 {
119 self
120 }
121}
122
123pub trait AggregateValue: Copy + 'static {
126 type Number: AggregateNumber;
128
129 fn number(self) -> Self::Number;
131}
132
133macro_rules! impl_aggregate_value {
134 ($($ty:ty),*) => {
135 $(
136 impl AggregateValue for $ty {
137 type Number = $ty;
138
139 fn number(self) -> $ty {
140 self
141 }
142 }
143 )*
144 };
145}
146
147impl_aggregate_value!(i32, i64, f32, f64);
148
149impl<X: AggregateNumber> AggregateValue for Option<X> {
150 type Number = X;
151
152 fn number(self) -> X {
153 self.unwrap_or(X::ZERO)
154 }
155}