1use std::io::{Cursor, Read};
2
3use crate::types::VarInt;
4
5pub trait Decoder {
6 fn decode<T: Read>(buf: &mut T) -> anyhow::Result<Self>
7 where
8 Self: Sized;
9
10 fn from_bytes(bytes: &[u8]) -> anyhow::Result<Self>
11 where
12 Self: Sized,
13 {
14 let mut cursor = Cursor::new(bytes);
15 Self::decode(&mut cursor)
16 }
17}
18
19impl Decoder for bool {
20 fn decode<T: Read>(buf: &mut T) -> anyhow::Result<Self> {
21 let mut byte = [0];
22 buf.read_exact(&mut byte)?;
23 let byte = byte[0];
24
25 match byte {
26 0 => Ok(false),
27 1 => Ok(true),
28 _ => anyhow::bail!("Invalid boolean value"),
29 }
30 }
31}
32
33impl Decoder for String {
34 fn decode<T: Read>(buf: &mut T) -> anyhow::Result<Self> {
35 let length = VarInt::decode(buf)?.0 as usize;
36
37 let max_length = i16::MAX as usize;
38 if length > max_length {
39 anyhow::bail!(
40 "String length {} exceeds maximum allowed length of {}",
41 length,
42 max_length
43 );
44 }
45
46 let mut bytes = vec![0; length];
47 buf.read_exact(&mut bytes)?;
48
49 let s = std::str::from_utf8(&bytes)?;
50 Ok(s.to_string())
51 }
52}
53
54macro_rules! impl_number_decoder {
55 ($typ:ty) => {
56 impl Decoder for $typ {
57 fn decode<T: Read>(buf: &mut T) -> anyhow::Result<Self> {
58 let mut bytes = [0; std::mem::size_of::<Self>()];
59 buf.read_exact(&mut bytes)?;
60 Ok(Self::from_be_bytes(bytes))
61 }
62 }
63 };
64}
65
66impl_number_decoder!(u8);
67impl_number_decoder!(u16);
68impl_number_decoder!(u32);
69impl_number_decoder!(u64);
70impl_number_decoder!(u128);
71
72impl_number_decoder!(i8);
73impl_number_decoder!(i16);
74impl_number_decoder!(i32);
75impl_number_decoder!(i64);
76impl_number_decoder!(i128);
77
78impl_number_decoder!(f32);
79impl_number_decoder!(f64);