use crate::{unwrap_return, Serializable , leb128};
use std::convert::TryInto;
macro_rules! serializable_primitive {
($primitive:ty) => {
impl Serializable for $primitive {
fn serialize(&self) -> Vec<u8> {
self.to_be_bytes().to_vec()
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
data.drain(0..size_of::<$primitive>())
.as_slice().try_into().ok()
.map(|bytes| <$primitive>::from_be_bytes(bytes))
}
}
};
}
serializable_primitive!(f32);
serializable_primitive!(f64);
serializable_primitive!(u8);
serializable_primitive!(u16);
serializable_primitive!(u32);
serializable_primitive!(u64);
serializable_primitive!(u128);
serializable_primitive!(i8);
serializable_primitive!(i16);
serializable_primitive!(i32);
serializable_primitive!(i64);
serializable_primitive!(i128);
macro_rules! serializable_size {
($primitive:ty) => {
impl Serializable for $primitive {
fn serialize(&self) -> Vec<u8> {
leb128::serialize(*self)
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
leb128::parse(data)
}
}
};
}
serializable_size!(isize);
serializable_size!(usize);
impl Serializable for char {
fn serialize(&self) -> Vec<u8> {
(*self as u32).serialize()
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
u32::parse(data).and_then(char::from_u32)
}
}
impl Serializable for bool {
fn serialize(&self) -> Vec<u8> {
vec![if *self { 1 } else { 0 }]
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
u8::parse(data).map(|byte| byte != 0)
}
}
impl<T: Serializable, const N: usize> Serializable for [T; N] {
fn serialize(&self) -> Vec<u8> {
let mut result = vec![];
for item in self {
result.push(item.serialize());
}
result.concat()
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
let mut result = vec![];
for _ in 0..N {
result.push(unwrap_return!(T::parse(data)));
}
Self::try_from(result).ok()
}
}
macro_rules! tuple_impls {
() => {};
( ($idx:tt => $typ:ident), $( ($nidx:tt => $ntyp:ident), )* ) => {
impl<$typ: Serializable, $( $ntyp: Serializable ),*> Serializable for ($typ, $( $ntyp ),*) {
fn serialize(&self) -> Vec<u8> {
#[allow(unused_mut)]
let mut result = vec![self.$idx.serialize()];
$( result.push(self.$nidx.serialize()); )*
result.into_iter().rev().collect::<Vec<Vec<u8>>>().concat()
}
fn parse(data: &mut Vec<u8>) -> Option<Self> {
let $typ = unwrap_return!($typ::parse(data));
$(
let $ntyp = unwrap_return!($ntyp::parse(data));
)*
Some((
$typ,
$(
$ntyp
),*
))
}
}
tuple_impls!($( ($nidx => $ntyp), )*);
};
}
tuple_impls!(
(11 => _11),
(10 => _10),
(9 => _9),
(8 => _8),
(7 => _7),
(6 => _6),
(5 => _5),
(4 => _4),
(3 => _3),
(2 => _2),
(1 => _1),
(0 => _0),
);