moq_lite/coding/
decode.rs1use std::{borrow::Cow, string::FromUtf8Error};
2use thiserror::Error;
3
4pub trait Decode<V>: Sized {
8 fn decode<B: bytes::Buf>(buf: &mut B, version: V) -> Result<Self, DecodeError>;
10}
11
12#[derive(Error, Debug, Clone)]
14#[non_exhaustive]
15pub enum DecodeError {
16 #[error("short buffer")]
17 Short,
18
19 #[error("long buffer")]
20 Long,
21
22 #[error("invalid string")]
23 InvalidString(#[from] FromUtf8Error),
24
25 #[error("invalid message: {0:?}")]
26 InvalidMessage(u64),
27
28 #[error("invalid subscribe location")]
29 InvalidSubscribeLocation,
30
31 #[error("invalid value")]
32 InvalidValue,
33
34 #[error("too many")]
35 TooMany,
36
37 #[error("bounds exceeded")]
38 BoundsExceeded,
39
40 #[error("expected end")]
41 ExpectedEnd,
42
43 #[error("expected data")]
44 ExpectedData,
45
46 #[error("duplicate")]
47 Duplicate,
48
49 #[error("missing")]
50 Missing,
51
52 #[error("unsupported")]
53 Unsupported,
54
55 #[error("trailing bytes")]
56 TrailingBytes,
57
58 #[error("unsupported version")]
59 Version,
60}
61
62impl<V> Decode<V> for bool {
63 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
64 match u8::decode(r, version)? {
65 0 => Ok(false),
66 1 => Ok(true),
67 _ => Err(DecodeError::InvalidValue),
68 }
69 }
70}
71
72impl<V> Decode<V> for u8 {
73 fn decode<R: bytes::Buf>(r: &mut R, _: V) -> Result<Self, DecodeError> {
74 match r.has_remaining() {
75 true => Ok(r.get_u8()),
76 false => Err(DecodeError::Short),
77 }
78 }
79}
80
81impl<V> Decode<V> for u16 {
82 fn decode<R: bytes::Buf>(r: &mut R, _: V) -> Result<Self, DecodeError> {
83 match r.remaining() >= 2 {
84 true => Ok(r.get_u16()),
85 false => Err(DecodeError::Short),
86 }
87 }
88}
89
90impl<V: Copy> Decode<V> for String
91where
92 usize: Decode<V>,
93{
94 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
96 let v = Vec::<u8>::decode(r, version)?;
97 let str = String::from_utf8(v)?;
98
99 Ok(str)
100 }
101}
102
103impl<V: Copy> Decode<V> for Vec<u8>
104where
105 usize: Decode<V>,
106{
107 fn decode<B: bytes::Buf>(buf: &mut B, version: V) -> Result<Self, DecodeError> {
108 let size = usize::decode(buf, version)?;
109
110 if buf.remaining() < size {
111 return Err(DecodeError::Short);
112 }
113
114 let bytes = buf.copy_to_bytes(size);
115 Ok(bytes.to_vec())
116 }
117}
118
119impl<V> Decode<V> for i8 {
120 fn decode<R: bytes::Buf>(r: &mut R, _: V) -> Result<Self, DecodeError> {
121 if !r.has_remaining() {
122 return Err(DecodeError::Short);
123 }
124
125 Ok(((r.get_u8() as i16) - 128) as i8)
129 }
130}
131
132impl<V: Copy> Decode<V> for bytes::Bytes
133where
134 usize: Decode<V>,
135{
136 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
137 let len = usize::decode(r, version)?;
138 if r.remaining() < len {
139 return Err(DecodeError::Short);
140 }
141 let bytes = r.copy_to_bytes(len);
142 Ok(bytes)
143 }
144}
145
146impl<V: Copy> Decode<V> for Cow<'_, str>
148where
149 usize: Decode<V>,
150{
151 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
152 let s = String::decode(r, version)?;
153 Ok(Cow::Owned(s))
154 }
155}
156
157impl<V: Copy> Decode<V> for Option<u64>
158where
159 u64: Decode<V>,
160{
161 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
162 match u64::decode(r, version)? {
163 0 => Ok(None),
164 value => Ok(Some(value - 1)),
165 }
166 }
167}
168
169impl<V: Copy> Decode<V> for std::time::Duration
170where
171 u64: Decode<V>,
172{
173 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
174 let value = u64::decode(r, version)?;
175 Ok(Self::from_millis(value))
176 }
177}