Skip to main content

bincake_core/
serialize_num.rs

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