Skip to main content

mlt_core/
analyse.rs

1use enum_dispatch::enum_dispatch;
2
3use crate::v01::StreamMeta;
4
5/// What to calculate with [`Analyze::collect_statistic`].
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum StatType {
8    /// Geometry/Feature/id data size in bytes (excludes metadata overhead).
9    DecodedDataSize,
10    /// Metadata overhead in bytes (stream headers, names, extent, geometry types).
11    DecodedMetaSize,
12    /// Number of features (geometry entries).
13    FeatureCount,
14}
15
16/// Trait for estimating various size/count metrics.
17#[enum_dispatch]
18pub trait Analyze {
19    fn collect_statistic(&self, _stat: StatType) -> usize {
20        0
21    }
22
23    /// Call `cb` with the [`StreamMeta`] of every stream contained in `self`.
24    /// Default implementation is a no-op (types that hold no streams).
25    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}