1use crate::{
5 decoder::{
6 buffer::{DecoderBuffer, DecoderBufferResult},
7 buffer_mut::{DecoderBufferMut, DecoderBufferMutResult},
8 },
9 unaligned::{i24, i48, u24, u48},
10 DecoderError,
11};
12use byteorder::{ByteOrder, NetworkEndian};
13use core::{marker::PhantomData, mem::size_of};
14use zerocopy::{FromBytes, Immutable, Unaligned};
15
16pub trait DecoderValue<'a>: Sized {
17 fn decode(bytes: DecoderBuffer<'a>) -> DecoderBufferResult<'a, Self>;
18}
19
20pub trait DecoderValueMut<'a>: Sized {
21 fn decode_mut(bytes: DecoderBufferMut<'a>) -> DecoderBufferMutResult<'a, Self>;
22}
23
24#[macro_export]
25macro_rules! decoder_value {
26 (impl<$lt:lifetime $(, $generic:ident)*> $ty:ty {
27 fn decode($buffer:ident: Buffer) -> Result<$ret:ty> $impl:block
28 }) => {
29 impl<$lt $(, $generic: $crate::DecoderValue<$lt>)*> $crate::DecoderValue<$lt> for $ty {
30 #[inline]
31 fn decode($buffer: $crate::DecoderBuffer<$lt>) -> $crate::DecoderBufferResult<$lt, $ret> $impl
32 }
33
34 impl<$lt $(, $generic: $crate::DecoderValueMut<$lt>)*> $crate::DecoderValueMut<$lt> for $ty {
35 #[inline]
36 fn decode_mut($buffer: $crate::DecoderBufferMut<$lt>) -> $crate::DecoderBufferMutResult<$lt, $ret> $impl
37 }
38 };
39}
40
41macro_rules! decoder_value_byte {
42 ($ty:ident) => {
43 decoder_value!(
44 impl<'a> $ty {
45 fn decode(buffer: Buffer) -> Result<Self> {
46 let (value, buffer) = buffer.decode_slice(size_of::<Self>())?;
47 let value = value.as_less_safe_slice()[0] as $ty;
48 Ok((value, buffer))
49 }
50 }
51 );
52 };
53}
54
55decoder_value_byte!(u8);
56decoder_value_byte!(i8);
57
58macro_rules! decoder_value_network_endian {
59 ($call:ident, $ty:ty) => {
60 decoder_value!(
61 impl<'a> $ty {
62 fn decode(buffer: Buffer) -> Result<Self> {
63 let (value, buffer) = buffer.decode_slice(size_of::<Self>())?;
64 let value = value.as_less_safe_slice();
65 let value = NetworkEndian::$call(value);
66 Ok((value.into(), buffer))
67 }
68 }
69 );
70 };
71}
72
73decoder_value_network_endian!(read_u16, u16);
74decoder_value_network_endian!(read_i16, i16);
75decoder_value_network_endian!(read_u32, u32);
76decoder_value_network_endian!(read_i32, i32);
77decoder_value_network_endian!(read_u64, u64);
78decoder_value_network_endian!(read_i64, i64);
79decoder_value_network_endian!(read_u128, u128);
80decoder_value_network_endian!(read_i128, i128);
81decoder_value_network_endian!(read_f32, f32);
82decoder_value_network_endian!(read_f64, f64);
83
84macro_rules! decoder_value_unaligned_integer {
85 ($call:ident, $ty:ident, $bitsize:expr) => {
86 decoder_value!(
87 impl<'a> $ty {
88 fn decode(buffer: Buffer) -> Result<Self> {
89 let (value, buffer) = buffer.decode_slice($bitsize / 8)?;
90 let value = value.as_less_safe_slice();
91 let value = NetworkEndian::$call(value);
92 Ok(($ty::new_truncated(value), buffer))
93 }
94 }
95 );
96 };
97}
98
99decoder_value_unaligned_integer!(read_u24, u24, 24);
100decoder_value_unaligned_integer!(read_i24, i24, 24);
101decoder_value_unaligned_integer!(read_u48, u48, 48);
102decoder_value_unaligned_integer!(read_i48, i48, 48);
103
104decoder_value!(
105 impl<'a> DecoderBuffer<'a> {
106 fn decode(buffer: Buffer) -> Result<Self> {
107 let len = buffer.len();
108 let (slice, buffer) = buffer.decode_slice(len)?;
109 #[allow(clippy::useless_conversion)]
110 let slice = slice.into();
111 Ok((slice, buffer))
112 }
113 }
114);
115
116decoder_value!(
117 impl<'a> () {
118 fn decode(buffer: Buffer) -> Result<Self> {
119 Ok(((), buffer))
120 }
121 }
122);
123
124decoder_value!(
125 impl<'a, T> Option<T> {
126 fn decode(buffer: Buffer) -> Result<Self> {
127 if buffer.is_empty() {
128 Ok((None, buffer))
129 } else {
130 let (value, buffer) = buffer.decode()?;
131 Ok((Some(value), buffer))
132 }
133 }
134 }
135);
136
137impl<'a> DecoderValueMut<'a> for DecoderBufferMut<'a> {
138 #[inline]
139 fn decode_mut(buffer: DecoderBufferMut<'a>) -> DecoderBufferMutResult<'a, Self> {
140 let len = buffer.len();
141 buffer.decode_slice(len)
142 }
143}
144
145pub trait DecoderParameterizedValue<'a>: Sized {
148 type Parameter;
149
150 fn decode_parameterized(
151 parameter: Self::Parameter,
152 bytes: DecoderBuffer<'a>,
153 ) -> DecoderBufferResult<'a, Self>;
154}
155
156pub trait DecoderParameterizedValueMut<'a>: Sized {
159 type Parameter;
160
161 fn decode_parameterized_mut(
162 parameter: Self::Parameter,
163 bytes: DecoderBufferMut<'a>,
164 ) -> DecoderBufferMutResult<'a, Self>;
165}
166
167#[macro_export]
168macro_rules! decoder_parameterized_value {
169 (impl<$lt:lifetime $(, $generic:ident)*> $ty:ty {
170 fn decode($tag:ident: $tag_ty:ty, $buffer:ident: Buffer) -> Result<$ret:ty> $impl:block
171 }) => {
172 impl<$lt $(, $generic: $crate::DecoderValue<$lt>)*> $crate::DecoderParameterizedValue<$lt> for $ty {
173 type Parameter = $tag_ty;
174
175 #[inline]
176 fn decode_parameterized($tag: Self::Parameter, $buffer: $crate::DecoderBuffer<$lt>) -> $crate::DecoderBufferResult<$lt, $ret> $impl
177 }
178
179 impl<$lt $(, $generic: $crate::DecoderValueMut<$lt>)*> $crate::DecoderParameterizedValueMut<$lt> for $ty {
180 type Parameter = $tag_ty;
181
182 #[inline]
183 fn decode_parameterized_mut($tag: Self::Parameter, $buffer: $crate::DecoderBufferMut<$lt>) -> $crate::DecoderBufferMutResult<$lt, $ret> $impl
184 }
185 };
186}
187
188pub struct PrefixedBlob<'a, L> {
194 pub blob: &'a [u8],
195 phantom_length: PhantomData<L>,
196}
197
198impl<'a, L: Into<usize> + DecoderValue<'a>> DecoderValue<'a> for PrefixedBlob<'a, L> {
199 fn decode(bytes: DecoderBuffer<'a>) -> DecoderBufferResult<'a, Self> {
200 let (blob, remaining) = bytes.decode_slice_with_len_prefix::<L>()?;
201 let blob = blob.into_less_safe_slice();
202
203 let value = Self {
204 blob,
205 phantom_length: PhantomData,
206 };
207
208 Ok((value, remaining))
209 }
210}
211
212pub struct PrefixedList<'a, L, T> {
221 pub list: &'a [T],
222 phantom_length: PhantomData<L>,
223}
224
225impl<'a, L: Into<usize> + DecoderValue<'a>, T: FromBytes + Immutable + Unaligned> DecoderValue<'a>
226 for PrefixedList<'a, L, T>
227{
228 fn decode(bytes: DecoderBuffer<'a>) -> DecoderBufferResult<'a, Self> {
229 let (blob, remaining) = bytes.decode_slice_with_len_prefix::<L>()?;
230 let blob = blob.into_less_safe_slice();
231 let list = FromBytes::ref_from_bytes(blob).map_err(|_| {
232 DecoderError::InvariantViolation("blob length is not a multiple of element size")
233 })?;
234
235 let value = Self {
236 list,
237 phantom_length: PhantomData,
238 };
239
240 Ok((value, remaining))
241 }
242}
243
244impl<'a, const N: usize> DecoderValue<'a> for [u8; N] {
246 fn decode(bytes: DecoderBuffer<'a>) -> DecoderBufferResult<'a, Self> {
247 let (value, buffer) = bytes.decode_slice(N)?;
248 let value = value.into_less_safe_slice().try_into().map_err(|_| {
249 DecoderError::InvariantViolation("decode_slice returned a slice of the wrong length")
250 })?;
251 Ok((value, buffer))
252 }
253}
254
255impl<'a, const N: usize> DecoderValue<'a> for &'a [u8; N] {
256 fn decode(bytes: DecoderBuffer<'a>) -> DecoderBufferResult<'a, Self> {
257 let (value, buffer) = bytes.decode_slice(N)?;
258 let slice = value.into_less_safe_slice();
259 let value = slice.try_into().map_err(|_| {
260 DecoderError::InvariantViolation("decode_slice returned a slice of the wrong length")
261 })?;
262 Ok((value, buffer))
263 }
264}
265
266#[cfg(test)]
267mod tests {
268 use super::*;
269 use crate::DecoderBuffer;
270
271 #[test]
272 fn array_decode() {
273 let buf = DecoderBuffer::new(&[1, 2, 3, 4, 5]);
274 let (val, remaining) = buf.decode::<[u8; 3]>().unwrap();
275 assert_eq!(val, [1, 2, 3]);
276 assert_eq!(remaining.into_less_safe_slice(), &[4, 5]);
277
278 let buf = DecoderBuffer::new(&[]);
279 let (val, remaining) = buf.decode::<[u8; 0]>().unwrap();
280 assert_eq!(val, []);
281 assert!(remaining.is_empty());
282
283 assert!(DecoderBuffer::new(&[1, 2]).decode::<[u8; 4]>().is_err());
285 }
286
287 #[test]
288 fn ref_array_decode() {
289 let buf = DecoderBuffer::new(&[1, 2, 3, 4, 5]);
290 let (val, remaining) = buf.decode::<&[u8; 3]>().unwrap();
291 assert_eq!(val, &[1, 2, 3]);
292 assert_eq!(remaining.into_less_safe_slice(), &[4, 5]);
293
294 let buf = DecoderBuffer::new(&[]);
295 let (val, remaining) = buf.decode::<&[u8; 0]>().unwrap();
296 assert_eq!(val, &[]);
297 assert!(remaining.is_empty());
298
299 assert!(DecoderBuffer::new(&[1, 2]).decode::<&[u8; 4]>().is_err());
301 }
302
303 #[test]
304 fn prefixed_blob_decode() {
305 let buf = DecoderBuffer::new(&[3, 0xAA, 0xBB, 0xCC]);
307 let (blob, remaining) = buf.decode::<PrefixedBlob<u8>>().unwrap();
308 assert_eq!(blob.blob, &[0xAA, 0xBB, 0xCC]);
309 assert!(remaining.is_empty());
310
311 let mut data = vec![0x01, 0x00];
313 data.extend(core::iter::repeat_n(0xFFu8, 256));
314 let buf = DecoderBuffer::new(&data);
315 let (blob, remaining) = buf.decode::<PrefixedBlob<u16>>().unwrap();
316 assert_eq!(blob.blob.len(), 256);
317 assert!(remaining.is_empty());
318
319 assert!(DecoderBuffer::new(&[5, 0x01, 0x02])
321 .decode::<PrefixedBlob<u8>>()
322 .is_err());
323 assert!(DecoderBuffer::new(&[0x01, 0x00, 0xAA])
324 .decode::<PrefixedBlob<u16>>()
325 .is_err());
326 assert!(DecoderBuffer::new(&[0x01])
327 .decode::<PrefixedBlob<u16>>()
328 .is_err());
329 }
330
331 #[test]
332 fn prefixed_list_decode() {
333 let buf = DecoderBuffer::new(&[3, 10, 20, 30]);
335 let (list, remaining) = buf.decode::<PrefixedList<u8, u8>>().unwrap();
336 assert_eq!(list.list, &[10, 20, 30]);
337 assert!(remaining.is_empty());
338
339 let buf = DecoderBuffer::new(&[0x00, 0x04, 0x01, 0x02, 0x03, 0x04]);
341 let (list, remaining) = buf
342 .decode::<PrefixedList<u16, zerocopy::network_endian::U16>>()
343 .unwrap();
344 assert_eq!(list.list.len(), 2);
345 assert_eq!(list.list[0].get(), 0x0102);
346 assert_eq!(list.list[1].get(), 0x0304);
347 assert!(remaining.is_empty());
348
349 assert!(DecoderBuffer::new(&[5, 1, 2])
351 .decode::<PrefixedList<u8, u8>>()
352 .is_err());
353 assert!(DecoderBuffer::new(&[0x00, 0x03, 0x01, 0x02, 0x03])
354 .decode::<PrefixedList<u16, zerocopy::network_endian::U16>>()
355 .is_err());
356 }
357}