Skip to main content

mkv_element/
element.rs

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