use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use crate::adapter::net::channel::Visibility;
use crate::adapter::net::subnet::SubnetId;
use super::Summarizer;
#[derive(Clone)]
pub struct AggregatorConfig {
pub source_subnet: SubnetId,
pub summary_visibility: Visibility,
pub summary_targets: Vec<SubnetId>,
pub fold_kinds: Vec<u16>,
pub summary_interval: Duration,
pub custom_summarizers: HashMap<u16, Arc<dyn Summarizer>>,
}
impl AggregatorConfig {
pub fn new(source_subnet: SubnetId) -> Self {
Self {
source_subnet,
summary_visibility: Visibility::ParentVisible,
summary_targets: Vec::new(),
fold_kinds: Vec::new(),
summary_interval: Duration::from_secs(30),
custom_summarizers: HashMap::new(),
}
}
pub fn with_visibility(mut self, visibility: Visibility) -> Self {
self.summary_visibility = visibility;
self
}
pub fn with_targets(mut self, targets: Vec<SubnetId>) -> Self {
self.summary_targets = targets;
self
}
pub fn with_fold_kind(mut self, kind: u16) -> Self {
if !self.fold_kinds.contains(&kind) {
self.fold_kinds.push(kind);
}
self
}
pub fn with_interval(mut self, interval: Duration) -> Self {
self.summary_interval = interval;
self
}
pub fn with_custom_summarizer(mut self, kind: u16, summarizer: Arc<dyn Summarizer>) -> Self {
self.custom_summarizers.insert(kind, summarizer);
self
}
}
impl std::fmt::Debug for AggregatorConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("AggregatorConfig")
.field("source_subnet", &self.source_subnet)
.field("summary_visibility", &self.summary_visibility)
.field("summary_targets", &self.summary_targets)
.field("fold_kinds", &self.fold_kinds)
.field("summary_interval", &self.summary_interval)
.field("custom_summarizers_count", &self.custom_summarizers.len())
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builder_chain_round_trips_fields() {
let cfg = AggregatorConfig::new(SubnetId::new(&[3, 7]))
.with_visibility(Visibility::Exported)
.with_targets(vec![SubnetId::new(&[3]), SubnetId::new(&[4])])
.with_fold_kind(0x0001)
.with_fold_kind(0x0003)
.with_fold_kind(0x0001) .with_interval(Duration::from_secs(15));
assert_eq!(cfg.source_subnet, SubnetId::new(&[3, 7]));
assert_eq!(cfg.summary_visibility, Visibility::Exported);
assert_eq!(
cfg.summary_targets,
vec![SubnetId::new(&[3]), SubnetId::new(&[4])]
);
assert_eq!(cfg.fold_kinds, vec![0x0001u16, 0x0003u16]);
assert_eq!(cfg.summary_interval, Duration::from_secs(15));
assert!(cfg.custom_summarizers.is_empty());
}
#[test]
fn defaults_to_parent_visible_with_no_targets_or_folds() {
let cfg = AggregatorConfig::new(SubnetId::new(&[1]));
assert_eq!(cfg.summary_visibility, Visibility::ParentVisible);
assert!(cfg.summary_targets.is_empty());
assert!(cfg.fold_kinds.is_empty());
assert_eq!(cfg.summary_interval, Duration::from_secs(30));
}
}