schema_analysis/context/
aggregators.rs

1use std::{any::Any, fmt::Debug};
2
3use crate::{Aggregate, Coalesce, CoalescingAggregator};
4
5/// A collection of aggregators that should allow the user of the library to run arbitrary
6/// aggregation code on the data as it is being analyzed.
7///
8/// This is an experimental feature.
9#[derive(Debug)]
10pub struct Aggregators<V: ?Sized>(pub Vec<Box<dyn CoalescingAggregator<V>>>);
11
12impl<V: ?Sized> Aggregate<V> for Aggregators<V> {
13    fn aggregate(&mut self, value: &'_ V) {
14        for a in &mut self.0 {
15            a.aggregate(value)
16        }
17    }
18}
19impl<T: ?Sized + 'static> Coalesce for Aggregators<T> {
20    fn coalesce(&mut self, other: Aggregators<T>)
21    where
22        Self: Sized,
23    {
24        'outer: for o in other.0 {
25            let mut o: Box<dyn Any> = o.into_any();
26            for s in &mut self.0 {
27                // coalesce_any returns the value if it doesn't manage to coalesce it.
28                o = match s.coalesce_any(o) {
29                    Some(o) => o,
30                    None => continue 'outer,
31                }
32            }
33            let o = *o.downcast::<Box<dyn CoalescingAggregator<T>>>().unwrap();
34            self.0.push(o);
35        }
36    }
37}
38impl<T: ?Sized> Clone for Aggregators<T> {
39    fn clone(&self) -> Self {
40        Aggregators(self.0.clone())
41    }
42}
43impl<T: ?Sized> Default for Aggregators<T> {
44    fn default() -> Self {
45        Self(Default::default())
46    }
47}
48impl<V: ?Sized> From<Vec<Box<dyn CoalescingAggregator<V>>>> for Aggregators<V> {
49    fn from(value: Vec<Box<dyn CoalescingAggregator<V>>>) -> Self {
50        Self(value)
51    }
52}