vantage_api_pool/stats/
average.rs1use rust_decimal::prelude::*;
2use std::time::Duration;
3
4#[derive(Debug, Clone, Default, Copy)]
5pub struct Average {
6 total: Decimal,
7 count: Decimal,
8}
9
10impl Average {
11 pub fn new() -> Self {
12 Self {
13 total: Decimal::ZERO,
14 count: Decimal::ZERO,
15 }
16 }
17
18 pub fn add_sample(&mut self, value: Decimal) {
19 self.total += value;
20 self.count += Decimal::ONE;
21 }
22
23 pub fn get_value(&self) -> Decimal {
24 if self.count > Decimal::ZERO {
25 self.total / self.count
26 } else {
27 Decimal::ZERO
28 }
29 }
30
31 pub fn reset(&mut self) {
32 self.total = Decimal::ZERO;
33 self.count = Decimal::ZERO;
34 }
35
36 pub fn from_duration(duration: Duration) -> Self {
37 let mut avg = Self::new();
38 avg.add_sample(Decimal::from(duration.as_millis() as u64));
39 avg
40 }
41}
42
43impl std::ops::Add for Average {
44 type Output = Average;
45
46 fn add(self, other: Average) -> Average {
47 Average {
48 total: self.total + other.total,
49 count: self.count + other.count,
50 }
51 }
52}
53
54impl std::ops::Sub for Average {
55 type Output = Average;
56
57 fn sub(self, other: Average) -> Average {
58 Average {
59 total: self.total.saturating_sub(other.total),
60 count: self.count.saturating_sub(other.count),
61 }
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn test_average_operations() {
71 let mut first_second = Average::new();
73 first_second.add_sample(dec!(10));
74 assert_eq!(first_second.get_value(), dec!(10));
75
76 let mut second_second = Average::new();
78 second_second.add_sample(dec!(9));
79 assert_eq!(second_second.get_value(), dec!(9));
80
81 let two_seconds = first_second + second_second;
83 assert_eq!(two_seconds.get_value(), dec!(9.5));
84
85 let mut third_second = Average::new();
87 third_second.add_sample(dec!(8));
88 assert_eq!(third_second.get_value(), dec!(8));
89
90 let three_seconds = two_seconds + third_second;
92 assert_eq!(three_seconds.get_value(), dec!(9));
93
94 let without_first = three_seconds - first_second;
96 assert_eq!(without_first.get_value(), dec!(8.5));
97 }
98}