moq_lite/coding/
decode.rs

1use std::string::FromUtf8Error;
2use thiserror::Error;
3
4pub trait Decode: Sized {
5	fn decode<B: bytes::Buf>(buf: &mut B) -> Result<Self, DecodeError>;
6}
7
8/// A decode error.
9#[derive(Error, Debug, Clone)]
10pub enum DecodeError {
11	#[error("short buffer")]
12	Short,
13
14	#[error("invalid string")]
15	InvalidString(#[from] FromUtf8Error),
16
17	#[error("invalid message: {0:?}")]
18	InvalidMessage(u64),
19
20	#[error("invalid role: {0:?}")]
21	InvalidRole(u64),
22
23	#[error("invalid subscribe location")]
24	InvalidSubscribeLocation,
25
26	#[error("invalid value")]
27	InvalidValue,
28
29	#[error("bounds exceeded")]
30	BoundsExceeded,
31
32	#[error("expected end")]
33	ExpectedEnd,
34
35	#[error("expected data")]
36	ExpectedData,
37
38	#[error("too many bytes")]
39	TooManyBytes,
40
41	// TODO move these to ParamError
42	#[error("duplicate parameter")]
43	DupliateParameter,
44
45	#[error("missing parameter")]
46	MissingParameter,
47
48	#[error("invalid parameter")]
49	InvalidParameter,
50}
51
52impl Decode for u8 {
53	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
54		match r.has_remaining() {
55			true => Ok(r.get_u8()),
56			false => Err(DecodeError::Short),
57		}
58	}
59}
60
61impl Decode for String {
62	/// Decode a string with a varint length prefix.
63	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
64		let v = Vec::<u8>::decode(r)?;
65		let str = String::from_utf8(v)?;
66
67		Ok(str)
68	}
69}
70
71impl Decode for Vec<u8> {
72	fn decode<B: bytes::Buf>(buf: &mut B) -> Result<Self, DecodeError> {
73		let size = usize::decode(buf)?;
74
75		if buf.remaining() < size {
76			return Err(DecodeError::Short);
77		}
78
79		let bytes = buf.copy_to_bytes(size);
80		Ok(bytes.to_vec())
81	}
82}
83
84impl Decode for std::time::Duration {
85	fn decode<B: bytes::Buf>(buf: &mut B) -> Result<Self, DecodeError> {
86		let ms = u64::decode(buf)?;
87		Ok(std::time::Duration::from_micros(ms))
88	}
89}
90
91impl Decode for i8 {
92	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
93		if !r.has_remaining() {
94			return Err(DecodeError::Short);
95		}
96
97		// This is not the usual way of encoding negative numbers.
98		// i8 doesn't exist in the draft, but we use it instead of u8 for priority.
99		// A default of 0 is more ergonomic for the user than a default of 128.
100		Ok(((r.get_u8() as i16) - 128) as i8)
101	}
102}
103
104impl Decode for bytes::Bytes {
105	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
106		let len = usize::decode(r)?;
107		if r.remaining() < len {
108			return Err(DecodeError::Short);
109		}
110		let bytes = r.copy_to_bytes(len);
111		Ok(bytes)
112	}
113}