Skip to main content

mlt_core/frames/v01/
column.rs

1use std::io;
2use std::io::Write;
3
4use crate::MltError::ParsingColumnType;
5use crate::utils::{BinarySerializer as _, parse_string, parse_u8};
6use crate::v01::{Column, ColumnType};
7use crate::{MltRefResult, Parser};
8
9impl Column<'_> {
10    /// Parse a single column definition
11    pub fn from_bytes<'a>(input: &'a [u8], _parser: &mut Parser) -> MltRefResult<'a, Column<'a>> {
12        let (mut input, typ) = ColumnType::from_bytes(input)?;
13        let name = if typ.has_name() {
14            let pair = parse_string(input)?;
15            input = pair.0;
16            Some(pair.1)
17        } else {
18            None
19        };
20
21        Ok((
22            input,
23            Column {
24                typ,
25                name,
26                children: Vec::new(),
27            },
28        ))
29    }
30}
31
32impl ColumnType {
33    /// Parse a column type from u8
34    pub fn from_bytes(input: &[u8]) -> MltRefResult<'_, Self> {
35        let (input, value) = parse_u8(input)?;
36        let value = Self::try_from(value).or(Err(ParsingColumnType(value)))?;
37        Ok((input, value))
38    }
39    pub fn write_to<W: Write>(self, writer: &mut W) -> io::Result<()> {
40        writer.write_u8(self as u8)?;
41        Ok(())
42    }
43
44    /// Returns true if the column definition includes a name field in the serialized format.
45    /// Note: ID and Geometry columns use implicit naming and do not include a name field.
46    #[must_use]
47    pub fn has_name(self) -> bool {
48        !matches!(
49            self,
50            ColumnType::Id
51                | ColumnType::OptId
52                | ColumnType::LongId
53                | ColumnType::OptLongId
54                | ColumnType::Geometry
55        )
56    }
57
58    /// Check if the column type has a presence stream
59    #[must_use]
60    pub fn is_optional(self) -> bool {
61        (self as u8) & 1 != 0
62    }
63}