Skip to main content

bincake_core/
serialize_le.rs

1//! Implements `Serialize` for numeric types.
2//!
3//! This module also provides the `encode_le` macro for writing numbers in little-endian format to byte vectors.
4
5use taped::Tape;
6
7use crate::{DecodeError, EncodeError, Serialize};
8
9/// Writes a numeric value to the buffer in little-endian format.
10macro_rules! encode_le {
11    ($T:ty; $dest:expr, $num:expr) => {
12        $dest.extend_from_slice(&($num as $T).to_le_bytes())
13    };
14}
15
16/// Implements `Serialize` for numeric types.
17macro_rules! impl_serialize_num {
18    ($($T:ty),* $(,)?) => { $(
19        impl Serialize for $T {
20            fn encode(&self, dest: &mut Vec<u8>) -> Result<(), EncodeError> {
21                encode_le!($T; dest, *self);
22                Ok(())
23            }
24
25            fn decode(src: &mut Tape<'_, u8>) -> Result<Self, DecodeError> {
26                let size = size_of::<Self>();
27                let pos = src.pos;
28                let data = &src;
29                if pos + size > data.len() {
30                    return Err(DecodeError::Exhausted { pos });
31                }
32                let slice = &data[pos..pos + size];
33                src.pos += size;
34                let bytes = slice.try_into()
35                    .map_err(|_| DecodeError::Other {
36                        pos,
37                        cause: format!("Invalid length at index {}", pos)
38                    })?;
39                Ok(Self::from_le_bytes(bytes))
40            }
41        }
42    )*};
43}
44
45impl_serialize_num!(
46    u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64,
47);