serial_traits 1.1.2

A trait that allows you to serialize to and parse from Vec<u8> buffers. Comes with implementations for primitive types, String and generic collection types (if the item type implements the trait too.)
Documentation
use crate::{unwrap_return, Serializable /*, bin_slice, get_vec*/, 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!(f16); // halfs in rust are unstable, uncomment when they're stable
serializable_primitive!(f32);
serializable_primitive!(f64);
// serializable_primitive!(f128); // quadruples in rust are unstable, uncomment when they're stable

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);

// since usize/isize can vary in byte-length, we are treating them with leb128
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)
    }
}

// commented out because there are reference problems i am not smart enough to resolve
/*impl Serializable for &str {
    fn serialize(&self) -> Vec<u8> {
        let mut bytes = self.len().serialize();
        bytes.append(&mut self.clone().bytes().collect());
        bytes
    }

    fn parse(data: &mut Vec<u8>) -> Option<Self> {
        let string_byte_length = unwrap_return!(usize::parse(data));

        get_vec(string_byte_length, data)
            .map(|bytes| String::from_utf8(bytes)
                .ok().map(|string| Some(string.as_str()))
            ).as_deref()
    }
}

impl<T: Serializable> Serializable for &[T] {
    fn serialize(&self) -> Vec<u8> {
        let mut stuffs = self.len().serialize();

        stuffs.append(&mut bin_slice(self));

        stuffs
    }
    fn parse(data: &mut Vec<u8>) -> Option<Self> {
        let length = unwrap_return!(usize::parse(data));

        get_vec(length, data).map(|parsed| parsed.as_slice())
    }
}*/

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), )*);
    };
}

// i used _# because i needed an identifier for both vars and types
tuple_impls!(
    // you can extend this infinitely far afaik, but some features of tuples break after 12 values.
    (11 => _11),
    (10 => _10),
    (9 => _9),
    (8 => _8),
    (7 => _7),
    (6 => _6),
    (5 => _5),
    (4 => _4),
    (3 => _3),
    (2 => _2),
    (1 => _1),
    (0 => _0),
);