1use enum_dispatch::enum_dispatch;
2
3use crate::v01::StreamMeta;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum StatType {
8 DecodedDataSize,
10 DecodedMetaSize,
12 FeatureCount,
14}
15
16#[enum_dispatch]
18pub trait Analyze {
19 fn collect_statistic(&self, _stat: StatType) -> usize {
20 0
21 }
22
23 fn for_each_stream(&self, _cb: &mut dyn FnMut(StreamMeta)) {}
26}
27
28macro_rules! impl_statistics_fixed {
29 ($($ty:ty),+) => {
30 $(impl Analyze for $ty {
31 fn collect_statistic(&self, _stat: StatType) -> usize {
32 size_of::<$ty>()
33 }
34 }
35 impl Analyze for &[$ty] {
36 fn collect_statistic(&self, _stat: StatType) -> usize {
37 size_of::<$ty>() * self.len()
38 }
39 })+
40 };
41}
42
43impl_statistics_fixed!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64);
44
45impl Analyze for String {
46 fn collect_statistic(&self, _stat: StatType) -> usize {
47 self.len()
48 }
49}
50
51impl<T: Analyze> Analyze for Option<T> {
52 fn collect_statistic(&self, stat: StatType) -> usize {
53 self.as_ref().map_or(0, |v| v.collect_statistic(stat))
54 }
55 fn for_each_stream(&self, cb: &mut dyn FnMut(StreamMeta)) {
56 if let Some(v) = self {
57 v.for_each_stream(cb);
58 }
59 }
60}
61
62impl<T: Analyze> Analyze for [T] {
63 fn collect_statistic(&self, stat: StatType) -> usize {
64 self.iter().map(|v| v.collect_statistic(stat)).sum()
65 }
66 fn for_each_stream(&self, cb: &mut dyn FnMut(StreamMeta)) {
67 for v in self {
68 v.for_each_stream(cb);
69 }
70 }
71}
72
73impl<T: Analyze> Analyze for Vec<T> {
74 fn collect_statistic(&self, stat: StatType) -> usize {
75 self.as_slice().collect_statistic(stat)
76 }
77 fn for_each_stream(&self, cb: &mut dyn FnMut(StreamMeta)) {
78 self.as_slice().for_each_stream(cb);
79 }
80}