1use crate::base::*;
2use crate::error::Error;
3use crate::io::blocking_impl::*;
4
5use crate::*;
6
7pub trait Element: Sized {
9 const ID: VInt64;
11 const HAS_DEFAULT_VALUE: bool = false;
15
16 fn decode_body<B: Buf>(buf: &mut B) -> crate::Result<Self>;
18
19 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}