1use crate::base::*;
2use crate::error::Error;
3use crate::functional::*;
4use crate::io::blocking_impl::*;
5
6pub trait Element: Sized {
8 const ID: VInt64;
10 const HAS_DEFAULT_VALUE: bool = false;
14
15 fn decode_body(buf: &mut &[u8]) -> crate::Result<Self>;
17
18 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}