binser/
decode.rs

1use super::error::Error;
2use std::mem;
3
4/// A struct representing a slice from which values implementing `Decode` can be read.
5pub struct Reader<'a> {
6    data: &'a [u8],
7    offset: usize,
8}
9
10impl<'a> Reader<'a> {
11    /// Constructs a new `Reader` with the provided data slice.
12    pub fn new(data: &'a [u8]) -> Reader<'a> {
13        Reader { data, offset: 0 }
14    }
15
16    /// Reads bytes to a buffer.
17    pub fn read_bytes(&mut self, buffer: &mut [u8]) -> Result<(), Error> {
18        if self.data.len() - self.offset < buffer.len() {
19            return Err(Error::Overflow);
20        }
21
22        buffer.copy_from_slice(&self.data[self.offset..self.offset + buffer.len()]);
23        self.offset += buffer.len();
24
25        Ok(())
26    }
27
28    /// Reads a value implementing `Decode` from the data slice and advances its offset.
29    pub fn read<T>(&mut self) -> Result<T, Error>
30    where
31        T: Decode,
32    {
33        T::decode(self)
34    }
35
36    /// Reads a value implementing `Decode` from the data slice at a specified offset.
37    pub fn read_at<T>(&self, offset: usize) -> Result<T, Error>
38    where
39        T: Decode,
40    {
41        if offset >= self.data.len() {
42            return Err(Error::Overflow);
43        }
44
45        Reader {
46            data: self.data,
47            offset,
48        }
49        .read()
50    }
51}
52
53/// A trait representing values that can be read from a `Reader`.
54pub trait Decode: Sized {
55    fn decode(reader: &mut Reader) -> Result<Self, Error>;
56
57    /// Creates a temporary `Reader` and reads itself.
58    ///
59    /// Convenience method.
60    fn decode_in_place(data: &[u8]) -> Result<Self, Error> {
61        let mut reader = Reader::new(data);
62        reader.read()
63    }
64}
65
66macro_rules! impl_decode_number {
67    ($($ty:ty)*) => {
68        $(impl Decode for $ty {
69            fn decode(reader: &mut Reader) -> Result<$ty, Error> {
70                let mut bytes = [0u8; mem::size_of::<$ty>()];
71                reader.read_bytes(&mut bytes)?;
72
73                Ok(<$ty>::from_le_bytes(bytes))
74            }
75        })*
76    };
77}
78
79impl_decode_number!(i8 u8 i16 u16 i32 u32 i64 u64 f32 f64);
80
81macro_rules! impl_decode_array {
82    ($($length:expr)*) => {
83        $(impl<T> Decode for [T; $length]
84        where
85            T: Default + Clone + Copy + Decode
86        {
87            fn decode(reader: &mut Reader) -> Result<[T; $length], Error> {
88                let mut data = [Default::default(); $length];
89                for elem in &mut data {
90                    *elem = reader.read()?;
91                }
92
93                Ok(data)
94            }
95        })*
96    };
97}
98
99impl_decode_array!(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32);