mlt_core/utils/
analyze.rs1use std::ops::Deref;
2
3use enum_dispatch::enum_dispatch;
4
5use crate::LazyParsed;
6use crate::decoder::{ParsedProperty, ParsedScalar, ParsedSharedDict, ParsedStrings, StreamMeta};
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub enum StatType {
11 DecodedDataSize,
13 DecodedMetaSize,
15 FeatureCount,
17}
18
19#[enum_dispatch]
21pub trait Analyze {
22 fn collect_statistic(&self, _stat: StatType) -> usize {
23 0
24 }
25
26 fn for_each_stream(&self, _cb: &mut dyn FnMut(StreamMeta)) {}
29}
30
31macro_rules! impl_statistics_fixed {
32 ($($ty:ty),+) => {
33 $(impl Analyze for $ty {
34 fn collect_statistic(&self, _stat: StatType) -> usize {
35 size_of::<$ty>()
36 }
37 }
38 impl Analyze for &[$ty] {
39 fn collect_statistic(&self, _stat: StatType) -> usize {
40 size_of::<$ty>() * self.len()
41 }
42 })+
43 };
44}
45
46impl_statistics_fixed!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64);
47
48impl Analyze for String {
49 fn collect_statistic(&self, _stat: StatType) -> usize {
50 self.len()
51 }
52}
53
54impl<T: Analyze> Analyze for Option<T> {
55 fn collect_statistic(&self, stat: StatType) -> usize {
56 self.as_ref().map_or(0, |v| v.collect_statistic(stat))
57 }
58 fn for_each_stream(&self, cb: &mut dyn FnMut(StreamMeta)) {
59 if let Some(v) = self {
60 v.for_each_stream(cb);
61 }
62 }
63}
64
65impl<T: Analyze> Analyze for [T] {
66 fn collect_statistic(&self, stat: StatType) -> usize {
67 self.iter().map(|v| v.collect_statistic(stat)).sum()
68 }
69 fn for_each_stream(&self, cb: &mut dyn FnMut(StreamMeta)) {
70 for v in self {
71 v.for_each_stream(cb);
72 }
73 }
74}
75
76impl<T: Analyze> Analyze for Vec<T> {
77 fn collect_statistic(&self, stat: StatType) -> usize {
78 self.as_slice().collect_statistic(stat)
79 }
80 fn for_each_stream(&self, cb: &mut dyn FnMut(StreamMeta)) {
81 self.as_slice().for_each_stream(cb);
82 }
83}
84
85pub(crate) trait AnalyzeViaDeref {}
91
92impl<T: Analyze, R: Deref<Target = T> + AnalyzeViaDeref> Analyze for R {
93 fn collect_statistic(&self, stat: StatType) -> usize {
94 (**self).collect_statistic(stat)
95 }
96 fn for_each_stream(&self, cb: &mut dyn FnMut(StreamMeta)) {
97 (**self).for_each_stream(cb);
98 }
99}
100
101impl<Raw: Analyze, Parsed: Analyze> Analyze for LazyParsed<Raw, Parsed> {
102 fn collect_statistic(&self, stat: StatType) -> usize {
103 match self {
104 Self::Raw(encoded) => encoded.collect_statistic(stat),
105 Self::Parsed(decoded) => decoded.collect_statistic(stat),
106 Self::ParsingFailed => 0,
107 }
108 }
109
110 fn for_each_stream(&self, cb: &mut dyn FnMut(StreamMeta)) {
111 match self {
112 Self::Raw(encoded) => encoded.for_each_stream(cb),
113 Self::Parsed(decoded) => decoded.for_each_stream(cb),
114 Self::ParsingFailed => {}
115 }
116 }
117}