mkv_element/
element.rs

1use crate::base::*;
2use crate::error::Error;
3use crate::functional::*;
4use crate::io::blocking_impl::*;
5
6/// A Matroska element.
7pub trait Element: Sized {
8    /// EBML ID of the element.
9    const ID: VInt64;
10    /// Whether the element has a default value, as per Matroska specification.
11    /// If true, and the element is missing in a master element, it should be treated as if it were present with the default value.
12    /// If false, and the element is missing in a master element, it should be treated as an error.
13    const HAS_DEFAULT_VALUE: bool = false;
14
15    /// Decode the body of the element from a buffer.
16    fn decode_body(buf: &mut &[u8]) -> crate::Result<Self>;
17
18    /// Encode the body of the element to a buffer.
19    fn encode_body<B: BufMut>(&self, buf: &mut B) -> crate::Result<()>;
20}
21
22impl<T: Element> Decode for T {
23    fn decode(buf: &mut &[u8]) -> crate::Result<Self> {
24        let header = Header::decode(buf)?;
25        let body_size = *header.size as usize;
26        if buf.remaining() < body_size {
27            return Err(crate::error::Error::OutOfBounds);
28        }
29        let mut body = buf.slice(body_size);
30        let element = match T::decode_body(&mut body) {
31            Ok(e) => e,
32            Err(Error::OutOfBounds) => return Err(Error::OverDecode(Self::ID)),
33            Err(Error::ShortRead) => return Err(Error::UnderDecode(Self::ID)),
34            Err(e) => return Err(e),
35        };
36
37        if body.has_remaining() {
38            return Err(Error::UnderDecode(Self::ID));
39        }
40
41        buf.advance(body_size);
42        Ok(element)
43    }
44}
45
46impl<T: Element> Encode for T {
47    fn encode<B: BufMut>(&self, buf: &mut B) -> crate::Result<()> {
48        let mut body_buf = Vec::new();
49        self.encode_body(&mut body_buf)?;
50        let header = Header {
51            id: T::ID,
52            size: VInt64::new(body_buf.len() as u64),
53        };
54        header.encode(buf)?;
55        buf.append_slice(&body_buf);
56        Ok(())
57    }
58}
59
60impl<T: Element> ReadFrom for T {
61    fn read_from<R: std::io::Read>(r: &mut R) -> crate::Result<Self> {
62        let header = Header::read_from(r)?;
63        let body = header.read_body(r)?;
64        let element = match T::decode_body(&mut &body[..]) {
65            Ok(e) => e,
66            Err(Error::OutOfBounds) => return Err(Error::OverDecode(Self::ID)),
67            Err(Error::ShortRead) => return Err(Error::UnderDecode(Self::ID)),
68            Err(e) => return Err(e),
69        };
70        Ok(element)
71    }
72}
73
74#[cfg(feature = "tokio")]
75#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
76impl<T: Element> crate::io::tokio_impl::AsyncReadFrom for T {
77    async fn async_read_from<R: tokio::io::AsyncRead + Unpin>(r: &mut R) -> crate::Result<Self> {
78        let header = Header::async_read_from(r).await?;
79        let body = header.read_body_tokio(r).await?;
80        let element = match T::decode_body(&mut &body[..]) {
81            Ok(e) => e,
82            Err(Error::OutOfBounds) => return Err(Error::OverDecode(Self::ID)),
83            Err(Error::ShortRead) => return Err(Error::UnderDecode(Self::ID)),
84            Err(e) => return Err(e),
85        };
86        Ok(element)
87    }
88}