1use 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")]
18 Short,
19
20 #[error("long buffer")]
22 Long,
23
24 #[error("invalid string")]
26 InvalidString(#[from] FromUtf8Error),
27
28 #[error("invalid message: {0:?}")]
30 InvalidMessage(u64),
31
32 #[error("invalid subscribe location")]
34 InvalidSubscribeLocation,
35
36 #[error("invalid value")]
38 InvalidValue,
39
40 #[error("too many")]
42 TooMany,
43
44 #[error("bounds exceeded")]
46 BoundsExceeded,
47
48 #[error("expected end")]
50 ExpectedEnd,
51
52 #[error("expected data")]
54 ExpectedData,
55
56 #[error("duplicate")]
58 Duplicate,
59
60 #[error("missing")]
62 Missing,
63
64 #[error("unsupported")]
66 Unsupported,
67
68 #[error("trailing bytes")]
70 TrailingBytes,
71
72 #[error("unsupported version")]
74 Version,
75}
76
77impl<V> Decode<V> for bool {
78 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
79 match u8::decode(r, version)? {
80 0 => Ok(false),
81 1 => Ok(true),
82 _ => Err(DecodeError::InvalidValue),
83 }
84 }
85}
86
87impl<V> Decode<V> for u8 {
88 fn decode<R: bytes::Buf>(r: &mut R, _: V) -> Result<Self, DecodeError> {
89 match r.has_remaining() {
90 true => Ok(r.get_u8()),
91 false => Err(DecodeError::Short),
92 }
93 }
94}
95
96impl<V> Decode<V> for u16 {
97 fn decode<R: bytes::Buf>(r: &mut R, _: V) -> Result<Self, DecodeError> {
98 match r.remaining() >= 2 {
99 true => Ok(r.get_u16()),
100 false => Err(DecodeError::Short),
101 }
102 }
103}
104
105impl<V: Copy> Decode<V> for String
106where
107 usize: Decode<V>,
108{
109 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
111 let v = Vec::<u8>::decode(r, version)?;
112 let str = String::from_utf8(v)?;
113
114 Ok(str)
115 }
116}
117
118impl<V: Copy> Decode<V> for Vec<u8>
119where
120 usize: Decode<V>,
121{
122 fn decode<B: bytes::Buf>(buf: &mut B, version: V) -> Result<Self, DecodeError> {
123 let size = usize::decode(buf, version)?;
124
125 if buf.remaining() < size {
126 return Err(DecodeError::Short);
127 }
128
129 let bytes = buf.copy_to_bytes(size);
130 Ok(bytes.to_vec())
131 }
132}
133
134impl<V> Decode<V> for i8 {
135 fn decode<R: bytes::Buf>(r: &mut R, _: V) -> Result<Self, DecodeError> {
136 if !r.has_remaining() {
137 return Err(DecodeError::Short);
138 }
139
140 Ok(((r.get_u8() as i16) - 128) as i8)
144 }
145}
146
147impl<V: Copy> Decode<V> for bytes::Bytes
148where
149 usize: Decode<V>,
150{
151 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
152 let len = usize::decode(r, version)?;
153 if r.remaining() < len {
154 return Err(DecodeError::Short);
155 }
156 let bytes = r.copy_to_bytes(len);
157 Ok(bytes)
158 }
159}
160
161impl<V: Copy> Decode<V> for Cow<'_, str>
163where
164 usize: Decode<V>,
165{
166 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
167 let s = String::decode(r, version)?;
168 Ok(Cow::Owned(s))
169 }
170}
171
172impl<V: Copy> Decode<V> for Option<u64>
173where
174 u64: Decode<V>,
175{
176 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
177 match u64::decode(r, version)? {
178 0 => Ok(None),
179 value => Ok(Some(value - 1)),
180 }
181 }
182}
183
184impl<V: Copy> Decode<V> for std::time::Duration
185where
186 u64: Decode<V>,
187{
188 fn decode<R: bytes::Buf>(r: &mut R, version: V) -> Result<Self, DecodeError> {
189 let value = u64::decode(r, version)?;
190 Ok(Self::from_millis(value))
191 }
192}