1use alloc::vec::Vec;
2use core::{mem::MaybeUninit, str::Utf8Error};
3use thiserror::Error;
4
5#[derive(Debug, Error, PartialEq, Eq)]
6pub struct DecodeError {
7 kind: DecodeErrorKind,
8 type_name: &'static str,
9}
10
11impl DecodeError {
12 pub fn new<T>(kind: DecodeErrorKind) -> Self {
13 Self {
14 kind,
15 type_name: core::any::type_name::<T>(),
16 }
17 }
18
19 pub const fn kind(&self) -> DecodeErrorKind {
20 self.kind
21 }
22}
23
24impl core::fmt::Display for DecodeError {
25 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26 write!(f, "Failed to decode {}: {}", self.type_name, self.kind)
27 }
28}
29
30#[derive(Error, Clone, Copy, Debug, PartialEq, Eq)]
31pub enum DecodeErrorKind {
32 #[error("Packet was too short.")]
33 UnexpectedEnd,
34
35 #[error(
36 "Could not decode {name} with unexpected byte. Found {value:x}, expected one of: {expected:x?}."
37 )]
38 UnexpectedByte {
39 name: &'static str,
40 value: u8,
41 expected: &'static [u8],
42 },
43
44 #[error("Packet did not have a valid header sequence.")]
45 InvalidHeader,
46
47 #[error("String ran past expected null terminator.")]
48 UnterminatedString,
49
50 #[error(transparent)]
51 Utf8Error(#[from] Utf8Error),
52}
53
54impl<T: Decode> DecodeWithLength for Vec<T> {
55 fn decode_with_len(data: &mut &[u8], len: usize) -> Result<Self, DecodeError> {
56 let mut vec = Vec::with_capacity(len);
57 for _ in 0..len {
58 vec.push(T::decode(data)?);
59 }
60 Ok(vec)
61 }
62}
63
64pub trait Decode {
70 fn decode(data: &mut &[u8]) -> Result<Self, DecodeError>
80 where
81 Self: Sized;
82}
83
84pub trait DecodeWithLength {
94 fn decode_with_len(data: &mut &[u8], len: usize) -> Result<Self, DecodeError>
105 where
106 Self: Sized;
107}
108
109impl Decode for () {
110 fn decode(_data: &mut &[u8]) -> Result<Self, DecodeError> {
111 Ok(())
112 }
113}
114
115macro_rules! impl_decode_for_primitive {
116 ($($t:ty),*) => {
117 $(
118 impl Decode for $t {
119 fn decode(data: &mut &[u8]) -> Result<Self, DecodeError> {
120 let bytes = data.get(..size_of::<Self>()).ok_or_else(|| DecodeError::new::<Self>(DecodeErrorKind::UnexpectedEnd))?;
121 *data = &data[size_of::<Self>()..];
122 Ok(Self::from_le_bytes(bytes.try_into().unwrap()))
123 }
124 }
125 )*
126 };
127}
128
129impl_decode_for_primitive!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
130
131impl<const N: usize, T: Decode> Decode for [T; N] {
133 fn decode(data: &mut &[u8]) -> Result<Self, DecodeError> {
134 let mut arr: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
135
136 for i in 0..N {
137 arr[i] = MaybeUninit::new(T::decode(data)?);
138 }
139
140 Ok(unsafe { core::mem::transmute_copy::<_, [T; N]>(&arr) })
141 }
142}