1use crate::base::*;
2use crate::error::Error;
3use crate::functional::*;
4use crate::io::ReadFrom;
5
6pub trait Element: Sized {
8 const ID: VInt64;
9 fn decode_body(buf: &mut &[u8]) -> crate::Result<Self>;
10 fn encode_body<B: BufMut>(&self, buf: &mut B) -> crate::Result<()>;
11}
12
13impl<T: Element> Decode for T {
14 fn decode(buf: &mut &[u8]) -> crate::Result<Self> {
15 let header = Header::decode(buf)?;
16 let body_size = *header.size as usize;
17 if buf.remaining() < body_size {
18 return Err(crate::error::Error::OutOfBounds);
19 }
20 let mut body = buf.slice(body_size);
21 let element = match T::decode_body(&mut body) {
22 Ok(e) => e,
23 Err(Error::OutOfBounds) => return Err(Error::OverDecode(Self::ID)),
24 Err(Error::ShortRead) => return Err(Error::UnderDecode(Self::ID)),
25 Err(e) => return Err(e),
26 };
27
28 if body.has_remaining() {
29 return Err(Error::UnderDecode(Self::ID));
30 }
31
32 buf.advance(body_size);
33 Ok(element)
34 }
35}
36
37impl<T: Element> Encode for T {
38 fn encode<B: BufMut>(&self, buf: &mut B) -> crate::Result<()> {
39 let mut body_buf = Vec::new();
40 self.encode_body(&mut body_buf)?;
41 let header = Header {
42 id: T::ID,
43 size: VInt64(body_buf.len() as u64),
44 };
45 header.encode(buf)?;
46 buf.append_slice(&body_buf);
47 Ok(())
48 }
49}
50
51impl<T: Element> ReadFrom for T {
52 fn read_from<R: std::io::Read>(r: &mut R) -> crate::Result<Self> {
53 let header = Header::read_from(r)?;
54 let body = header.read_body(r)?;
55 let element = match T::decode_body(&mut &body[..]) {
56 Ok(e) => e,
57 Err(Error::OutOfBounds) => return Err(Error::OverDecode(Self::ID)),
58 Err(Error::ShortRead) => return Err(Error::UnderDecode(Self::ID)),
59 Err(e) => return Err(e),
60 };
61 Ok(element)
62 }
63}