1use crate::coding::{self, DecodeError, Sizer};
2use crate::ietf::Version;
3use std::fmt::Debug;
4
5use bytes::{Buf, BufMut};
6
7pub trait Message: Sized + Debug {
14 const ID: u64;
15
16 fn encode_msg<W: BufMut>(&self, w: &mut W, version: Version);
18
19 fn decode_msg<B: Buf>(buf: &mut B, version: Version) -> Result<Self, DecodeError>;
21}
22
23impl<T: Message> coding::Encode<Version> for T {
24 fn encode<W: BufMut>(&self, w: &mut W, version: Version) {
25 let mut sizer = Sizer::default();
28 self.encode_msg(&mut sizer, version);
29 let size: u16 = sizer.size.try_into().expect("message too large");
30 size.encode(w, version);
31 self.encode_msg(w, version);
32 }
33}
34
35impl<T: Message> coding::Decode<Version> for T {
36 fn decode<B: Buf>(buf: &mut B, version: Version) -> Result<Self, DecodeError> {
37 let size = u16::decode(buf, version)?;
38 let mut limited = buf.take(size as usize);
39 let result = Self::decode_msg(&mut limited, version)?;
40 if limited.remaining() > 0 {
41 return Err(DecodeError::Long);
42 }
43 Ok(result)
44 }
45}