Skip to main content

bamcensus_core/ops/agg/
numeric_aggregation.rs

1use std::fmt::Display;
2
3use clap::ValueEnum;
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize, Clone, ValueEnum, Default)]
7#[serde(rename_all = "snake_case")]
8/// operations for aggregating a collection of numeric values
9pub enum NumericAggregation {
10    #[default]
11    Sum,
12    Mean,
13}
14
15impl NumericAggregation {
16    pub fn aggregate(&self, values: &mut dyn Iterator<Item = f64>) -> f64 {
17        use NumericAggregation as Fn;
18        match self {
19            Fn::Sum => values.fold(0.0, |acc, v| acc + v),
20            Fn::Mean => {
21                let (acc, n) = values.fold((0.0, 0.0), |(acc, n), v| (acc + v, n + 1.0));
22                if n == 0.0 {
23                    0.0
24                } else {
25                    acc / n
26                }
27            }
28        }
29    }
30}
31
32impl Display for NumericAggregation {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        match self {
35            NumericAggregation::Sum => write!(f, "sum"),
36            NumericAggregation::Mean => write!(f, "mean"),
37        }
38    }
39}