moq_lite/lite/
message.rs

1use bytes::{Buf, BufMut};
2
3use crate::{
4	coding::{Decode, DecodeError, Encode, Sizer},
5	lite::Version,
6};
7
8/// A trait for messages that are automatically size-prefixed during encoding/decoding.
9///
10/// This trait wraps the existing Encode/Decode traits and automatically handles:
11/// - Prefixing messages with their encoded size during encoding
12/// - Reading the size prefix and validating exact consumption during decoding
13/// - Ensuring no bytes are left over or missing after decoding
14pub trait Message: Sized {
15	/// Encode this message with a size prefix.
16	fn encode_msg<W: BufMut>(&self, w: &mut W, version: Version);
17
18	/// Decode a size-prefixed message, ensuring exact size consumption.
19	fn decode_msg<B: Buf>(buf: &mut B, version: Version) -> Result<Self, DecodeError>;
20}
21
22// Blanket implementation for all types that implement Encode + Decode
23impl<T: Message> Encode<Version> for T {
24	fn encode<W: BufMut>(&self, w: &mut W, version: Version) {
25		let mut sizer = Sizer::default();
26		Message::encode_msg(self, &mut sizer, version);
27		sizer.size.encode(w, version);
28		Message::encode_msg(self, w, version);
29	}
30}
31
32impl<T: Message> Decode<Version> for T {
33	fn decode<B: Buf>(buf: &mut B, version: Version) -> Result<Self, DecodeError> {
34		let size = usize::decode(buf, version)?;
35		let mut limited = buf.take(size);
36		let result = Message::decode_msg(&mut limited, version)?;
37		if limited.remaining() > 0 {
38			return Err(DecodeError::Long);
39		}
40
41		Ok(result)
42	}
43}