moq_transfork/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	// TODO move these to ParamError
39	#[error("duplicate parameter")]
40	DupliateParameter,
41
42	#[error("missing parameter")]
43	MissingParameter,
44
45	#[error("invalid parameter")]
46	InvalidParameter,
47}
48
49impl Decode for u8 {
50	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
51		match r.has_remaining() {
52			true => Ok(r.get_u8()),
53			false => Err(DecodeError::Short),
54		}
55	}
56}
57
58impl Decode for String {
59	/// Decode a string with a varint length prefix.
60	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
61		let v = Vec::<u8>::decode(r)?;
62		let str = String::from_utf8(v)?;
63
64		Ok(str)
65	}
66}
67
68impl<T: Decode> Decode for Vec<T> {
69	fn decode<B: bytes::Buf>(buf: &mut B) -> Result<Self, DecodeError> {
70		let size = usize::decode(buf)?;
71
72		// Don't allocate more than 1024 elements upfront
73		let mut v = Vec::with_capacity(size.min(1024));
74
75		for _ in 0..size {
76			v.push(T::decode(buf)?);
77		}
78
79		Ok(v)
80	}
81}
82
83impl Decode for std::time::Duration {
84	fn decode<B: bytes::Buf>(buf: &mut B) -> Result<Self, DecodeError> {
85		let ms = u64::decode(buf)?;
86		Ok(std::time::Duration::from_micros(ms))
87	}
88}
89
90impl Decode for i8 {
91	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
92		if !r.has_remaining() {
93			return Err(DecodeError::Short);
94		}
95
96		// This is not the usual way of encoding negative numbers.
97		// i8 doesn't exist in the draft, but we use it instead of u8 for priority.
98		// A default of 0 is more ergonomic for the user than a default of 128.
99		Ok(((r.get_u8() as i16) - 128) as i8)
100	}
101}
102
103impl Decode for bytes::Bytes {
104	fn decode<R: bytes::Buf>(r: &mut R) -> Result<Self, DecodeError> {
105		let len = usize::decode(r)?;
106		if r.remaining() < len {
107			return Err(DecodeError::Short);
108		}
109		let bytes = r.copy_to_bytes(len);
110		Ok(bytes)
111	}
112}