macro_rules! ebml_elements {
($($(#[doc = $doc:literal])* name = $element_name:ident, original_name = $original_name:expr, id = $id:expr, variant = $variant:ident;)+) => {
use serde::{Serialize, Serializer};
#[derive(Debug, PartialEq)]
pub enum Type {
Unsigned,
Signed,
Float,
String,
Utf8,
Date,
Master,
Binary,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Id {
Unknown(u32),
Corrupted,
$(
$(#[doc = $doc])*
$element_name,
)+
}
impl Id {
pub fn new(id: u32) -> Self {
match id {
$($id => Self::$element_name,)+
_ => Self::Unknown(id)
}
}
pub fn corrupted() -> Self {
Self::Corrupted
}
pub fn get_type(&self) -> Type {
match self {
$(Id::$element_name => Type::$variant,)+
Id::Unknown(_) | Id::Corrupted => Type::Binary
}
}
pub fn get_value(&self) -> Option<u32> {
match self {
$(Id::$element_name => Some($id),)+
Id::Unknown(value) => Some(*value),
Id::Corrupted => None
}
}
}
impl Serialize for Id {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
match *self {
$(Id::$element_name => s.serialize_str($original_name),)+
Id::Unknown(value) => s.serialize_str(&format!("0x{:X}", value)),
Id::Corrupted => s.serialize_str("Corrupted")
}
}
}
};
}
macro_rules! ebml_enumerations {
($($(#[doc = $enum_doc:expr])* $id:ident { $($(#[doc = $variant_doc:expr])* $variant:ident = $value:expr, original_label = $original_label:expr;)+ };)+) => {
use crate::elements::Id;
use serde::Serialize;
$(
$(#[doc = $enum_doc])*
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
pub enum $id {
$(
$(#[doc = $variant_doc])*
#[serde(rename = $original_label)]
$variant,
)+
}
impl $id {
pub fn new(value: u64) -> Option<Self> {
match value {
$($value => Some(Self::$variant),)+
_ => None,
}
}
}
)+
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
#[serde(untagged)]
pub enum Enumeration {
$(
$(#[doc = $enum_doc])*
$id($id),
)+
}
impl Enumeration {
pub fn new(id: &Id, value: u64) -> Option<Self> {
match id {
$(
Id::$id => $id::new(value).map(Self::$id),
)+
_ => None
}
}
}
};
}
pub(crate) use ebml_elements;
pub(crate) use ebml_enumerations;