Skip to main content

mlt_core/frames/v01/property/
decode.rs

1use crate::MltError::{self};
2use crate::enc_dec::Decode;
3use crate::utils::apply_present;
4use crate::v01::{
5    ParsedPresence, ParsedProperty, ParsedScalar, RawPresence, RawProperty, StagedProperty,
6    StagedScalar, StagedStrings,
7};
8use crate::{Decoder, MltResult};
9
10impl<'a, T: Copy + PartialEq> ParsedScalar<'a, T> {
11    #[must_use]
12    pub fn new(name: &'a str, values: Vec<Option<T>>) -> Self {
13        Self { name, values }
14    }
15
16    pub fn from_parts(
17        name: &'a str,
18        presence: RawPresence<'a>,
19        values: Vec<T>,
20        dec: &mut Decoder,
21    ) -> MltResult<Self> {
22        Ok(Self {
23            name,
24            values: apply_present(presence, values, dec)?,
25        })
26    }
27}
28
29impl ParsedPresence {
30    #[must_use]
31    pub fn bools(&self, non_null_count: usize) -> Vec<bool> {
32        self.0.clone().unwrap_or_else(|| vec![true; non_null_count])
33    }
34
35    #[must_use]
36    pub fn feature_count(&self, non_null_count: usize) -> usize {
37        self.0.as_ref().map_or(non_null_count, Vec::len)
38    }
39}
40
41impl<'a> ParsedProperty<'a> {
42    #[must_use]
43    pub fn bool(name: &'a str, values: Vec<Option<bool>>) -> Self {
44        Self::Bool(ParsedScalar::new(name, values))
45    }
46    #[must_use]
47    pub fn i8(name: &'a str, values: Vec<Option<i8>>) -> Self {
48        Self::I8(ParsedScalar::new(name, values))
49    }
50    #[must_use]
51    pub fn u8(name: &'a str, values: Vec<Option<u8>>) -> Self {
52        Self::U8(ParsedScalar::new(name, values))
53    }
54    #[must_use]
55    pub fn i32(name: &'a str, values: Vec<Option<i32>>) -> Self {
56        Self::I32(ParsedScalar::new(name, values))
57    }
58    #[must_use]
59    pub fn u32(name: &'a str, values: Vec<Option<u32>>) -> Self {
60        Self::U32(ParsedScalar::new(name, values))
61    }
62    #[must_use]
63    pub fn i64(name: &'a str, values: Vec<Option<i64>>) -> Self {
64        Self::I64(ParsedScalar::new(name, values))
65    }
66    #[must_use]
67    pub fn u64(name: &'a str, values: Vec<Option<u64>>) -> Self {
68        Self::U64(ParsedScalar::new(name, values))
69    }
70    #[must_use]
71    pub fn f32(name: &'a str, values: Vec<Option<f32>>) -> Self {
72        Self::F32(ParsedScalar::new(name, values))
73    }
74    #[must_use]
75    pub fn f64(name: &'a str, values: Vec<Option<f64>>) -> Self {
76        Self::F64(ParsedScalar::new(name, values))
77    }
78}
79
80impl StagedProperty {
81    #[must_use]
82    pub fn bool(name: impl Into<String>, values: Vec<Option<bool>>) -> Self {
83        Self::Bool(StagedScalar {
84            name: name.into(),
85            values,
86        })
87    }
88    #[must_use]
89    pub fn i8(name: impl Into<String>, values: Vec<Option<i8>>) -> Self {
90        Self::I8(StagedScalar {
91            name: name.into(),
92            values,
93        })
94    }
95    #[must_use]
96    pub fn u8(name: impl Into<String>, values: Vec<Option<u8>>) -> Self {
97        Self::U8(StagedScalar {
98            name: name.into(),
99            values,
100        })
101    }
102    #[must_use]
103    pub fn i32(name: impl Into<String>, values: Vec<Option<i32>>) -> Self {
104        Self::I32(StagedScalar {
105            name: name.into(),
106            values,
107        })
108    }
109    #[must_use]
110    pub fn u32(name: impl Into<String>, values: Vec<Option<u32>>) -> Self {
111        Self::U32(StagedScalar {
112            name: name.into(),
113            values,
114        })
115    }
116    #[must_use]
117    pub fn i64(name: impl Into<String>, values: Vec<Option<i64>>) -> Self {
118        Self::I64(StagedScalar {
119            name: name.into(),
120            values,
121        })
122    }
123    #[must_use]
124    pub fn u64(name: impl Into<String>, values: Vec<Option<u64>>) -> Self {
125        Self::U64(StagedScalar {
126            name: name.into(),
127            values,
128        })
129    }
130    #[must_use]
131    pub fn f32(name: impl Into<String>, values: Vec<Option<f32>>) -> Self {
132        Self::F32(StagedScalar {
133            name: name.into(),
134            values,
135        })
136    }
137    #[must_use]
138    pub fn f64(name: impl Into<String>, values: Vec<Option<f64>>) -> Self {
139        Self::F64(StagedScalar {
140            name: name.into(),
141            values,
142        })
143    }
144    #[must_use]
145    pub fn str(name: impl Into<String>, values: Vec<Option<String>>) -> Self {
146        let mut s = StagedStrings::from(values);
147        s.name = name.into();
148        Self::Str(s)
149    }
150}
151
152impl<'a> Decode<ParsedProperty<'a>> for RawProperty<'a> {
153    fn decode(self, decoder: &mut Decoder) -> Result<ParsedProperty<'a>, MltError> {
154        RawProperty::decode(self, decoder)
155    }
156}
157
158impl<'a> RawProperty<'a> {
159    /// Decode into a [`ParsedProperty`], charging `dec` for every heap allocation.
160    ///
161    /// For scalar columns the output size is known from stream metadata, so
162    /// the budget is charged *before* decoding.  For string and shared-dict
163    /// columns the exact decoded size depends on compression, so the budget is
164    /// charged *after* decoding based on actual allocation sizes.
165    pub fn decode(self, dec: &mut Decoder) -> Result<ParsedProperty<'a>, MltError> {
166        /// Charge for the final `Vec<Option<T>>`, then decode the dense stream.
167        /// `$decode_method` is the typed `RawStream` method for element type `$ty`.
168        macro_rules! scalar_decode {
169            ($variant:ident, $ty:ty, $decode_method:ident, $v:expr, $dec:expr) => {{
170                ParsedProperty::$variant(ParsedScalar::from_parts(
171                    $v.name,
172                    $v.presence,
173                    $v.data.$decode_method($dec)?,
174                    $dec,
175                )?)
176            }};
177        }
178
179        Ok(match self {
180            Self::Bool(v) => scalar_decode!(Bool, bool, decode_bools, v, dec),
181            Self::I8(v) => scalar_decode!(I8, i8, decode_i8s, v, dec),
182            Self::U8(v) => scalar_decode!(U8, u8, decode_u8s, v, dec),
183            Self::I32(v) => scalar_decode!(I32, i32, decode_i32s, v, dec),
184            Self::U32(v) => scalar_decode!(U32, u32, decode_u32s, v, dec),
185            Self::I64(v) => scalar_decode!(I64, i64, decode_i64s, v, dec),
186            Self::U64(v) => scalar_decode!(U64, u64, decode_u64s, v, dec),
187            Self::F32(v) => scalar_decode!(F32, f32, decode_f32s, v, dec),
188            Self::F64(v) => scalar_decode!(F64, f64, decode_f64s, v, dec),
189            Self::Str(v) => ParsedProperty::Str(v.decode(dec)?),
190            Self::SharedDict(v) => ParsedProperty::SharedDict(v.decode(dec)?),
191        })
192    }
193}