ssz 0.2.0

Simple serialization implementation
Documentation
use crate::{Encode, Error, Decode, Compact, CompactRef, Add, Mul, Div, Codec};
use crate::utils::{encode_list, decode_list};
use generic_array::{GenericArray, ArrayLength};
use vecarray::VecArray;
use primitive_types::H256;
use typenum::Unsigned;
use core::convert::TryFrom;
use alloc::vec::Vec;

macro_rules! impl_builtin_fixed_uint_vector {
	( $( $t:ty ),* ) => { $(
		impl<L: ArrayLength<$t> + Unsigned> Codec for Compact<GenericArray<$t, L>>
		{
			type Size = Mul<<$t as Codec>::Size, L>;
		}

		impl<'a, L: ArrayLength<$t> + Unsigned> Codec for CompactRef<'a, GenericArray<$t, L>> where
			Compact<GenericArray<$t, L>>: Codec,
		{
			type Size = <Compact<GenericArray<$t, L>> as Codec>::Size;
		}

		impl<'a, L: ArrayLength<$t>> Encode for CompactRef<'a, GenericArray<$t, L>> where
			CompactRef<'a, GenericArray<$t, L>>: Codec
		{
			fn encode(&self) -> Vec<u8> {
				encode_list(self.0)
			}
		}

		impl<L: ArrayLength<$t>> Encode for Compact<GenericArray<$t, L>> where
			Compact<GenericArray<$t, L>>: Codec,
			for<'a> CompactRef<'a, GenericArray<$t, L>>: Encode
		{
			fn encode(&self) -> Vec<u8> {
				CompactRef(&self.0).encode()
			}
		}

		impl<L: ArrayLength<$t>> Decode for Compact<GenericArray<$t, L>> where
			Compact<GenericArray<$t, L>>: Codec,
		{
			fn decode(value: &[u8]) -> Result<Self, Error> {
				let decoded = decode_list::<$t>(value)?;
				if decoded.len() != L::to_usize() {
					return Err(Error::InvalidLength)
				}
				let mut ret = GenericArray::default();
				for i in 0..decoded.len() {
					ret[i] = decoded[i];
				}
				Ok(Compact(ret))
			}
		}

		impl<L: Unsigned> Codec for Compact<VecArray<$t, L>>
		{
			type Size = Mul<<$t as Codec>::Size, L>;
		}

		impl<'a, L: Unsigned> Codec for CompactRef<'a, VecArray<$t, L>> where
			Compact<VecArray<$t, L>>: Codec,
		{
			type Size = <Compact<VecArray<$t, L>> as Codec>::Size;
		}

		impl<'a, L: Unsigned> Encode for CompactRef<'a, VecArray<$t, L>> where
			CompactRef<'a, VecArray<$t, L>>: Codec
		{
			fn encode(&self) -> Vec<u8> {
				encode_list(self.0)
			}
		}

		impl<L: Unsigned> Encode for Compact<VecArray<$t, L>> where
			Compact<VecArray<$t, L>>: Codec,
			for<'a> CompactRef<'a, GenericArray<$t, L>>: Encode
		{
			fn encode(&self) -> Vec<u8> {
				CompactRef(&self.0).encode()
			}
		}

		impl<L: Unsigned> Decode for Compact<VecArray<$t, L>> where
			Compact<VecArray<$t, L>>: Codec,
		{
			fn decode(value: &[u8]) -> Result<Self, Error> {
				let decoded = decode_list::<$t>(value)?;
				if decoded.len() != L::to_usize() {
					return Err(Error::InvalidLength)
				}
				let mut ret = VecArray::default();
				for i in 0..decoded.len() {
					ret[i] = decoded[i];
				}
				Ok(Compact(ret))
			}
		}
	)* }
}

impl_builtin_fixed_uint_vector!(u8, u16, u32, u64, u128);

impl<L: ArrayLength<bool> + Unsigned> Codec for Compact<GenericArray<bool, L>> {
	type Size = Div<Add<L, typenum::U7>, typenum::U8>;
}

impl<'a, L: ArrayLength<bool> + Unsigned> Codec for CompactRef<'a, GenericArray<bool, L>> where
	Compact<GenericArray<bool, L>>: Codec,
{
	type Size = <Compact<GenericArray<bool, L>> as Codec>::Size;
}

impl<'a, L: ArrayLength<bool>> Encode for CompactRef<'a, GenericArray<bool, L>> where
	CompactRef<'a, GenericArray<bool, L>>: Codec
{
	fn encode(&self) -> Vec<u8> {
		let mut bytes = Vec::new();
        bytes.resize((self.0.len() + 7) / 8, 0u8);

        for i in 0..self.0.len() {
            bytes[i / 8] |= (self.0[i] as u8) << (i % 8);
        }
		bytes
	}
}

impl<L: ArrayLength<bool>> Encode for Compact<GenericArray<bool, L>> where
	Compact<GenericArray<bool, L>>: Codec,
	for<'a> CompactRef<'a, GenericArray<bool, L>>: Encode
{
	fn encode(&self) -> Vec<u8> {
		CompactRef(&self.0).encode()
	}
}

impl<L: ArrayLength<bool>> Decode for Compact<GenericArray<bool, L>> where
	Compact<GenericArray<bool, L>>: Codec,
{
	fn decode(value: &[u8]) -> Result<Self, Error> {
		let len = L::to_usize();
		let mut ret = GenericArray::default();
		for i in 0..len {
			if i / 8 >= value.len() {
				return Err(Error::IncorrectSize)
			}
			ret[i] = value[i / 8] & (1 << (i % 8)) != 0;
		}
		Ok(Compact(ret))
	}
}

impl<T: Codec, L: ArrayLength<T>> Codec for GenericArray<T, L> {
	type Size = Mul<<T as Codec>::Size, L>;
}

impl<T: Encode, L: ArrayLength<T>> Encode for GenericArray<T, L> where
	GenericArray<T, L>: Codec
{
	fn encode(&self) -> Vec<u8> {
		encode_list(&self)
	}
}

impl<T: Decode, L: ArrayLength<T>> Decode for GenericArray<T, L> where
	GenericArray<T, L>: Codec
{
	fn decode(value: &[u8]) -> Result<Self, Error> {
		let decoded = decode_list::<T>(value)?;

		GenericArray::from_exact_iter(decoded).ok_or(Error::InvalidLength)
	}
}

impl<L: Unsigned> Codec for Compact<VecArray<bool, L>> {
	type Size = Div<Add<L, typenum::U7>, typenum::U8>;
}

impl<'a, L: Unsigned> Codec for CompactRef<'a, VecArray<bool, L>> where
	Compact<VecArray<bool, L>>: Codec,
{
	type Size = <Compact<VecArray<bool, L>> as Codec>::Size;
}

impl<'a, L: Unsigned> Encode for CompactRef<'a, VecArray<bool, L>> where
	CompactRef<'a, VecArray<bool, L>>: Codec
{
	fn encode(&self) -> Vec<u8> {
		let mut bytes = Vec::new();
        bytes.resize((self.0.len() + 7) / 8, 0u8);

        for i in 0..self.0.len() {
            bytes[i / 8] |= (self.0[i] as u8) << (i % 8);
        }
		bytes
	}
}

impl<L: Unsigned> Encode for Compact<VecArray<bool, L>> where
	Compact<VecArray<bool, L>>: Codec,
	for<'a> CompactRef<'a, VecArray<bool, L>>: Encode
{
	fn encode(&self) -> Vec<u8> {
		CompactRef(&self.0).encode()
	}
}

impl<L: Unsigned> Decode for Compact<VecArray<bool, L>> where
	Compact<VecArray<bool, L>>: Codec,
{
	fn decode(value: &[u8]) -> Result<Self, Error> {
		let len = L::to_usize();
		let mut ret = VecArray::default();
		for i in 0..len {
			if i / 8 >= value.len() {
				return Err(Error::IncorrectSize)
			}
			ret[i] = value[i / 8] & (1 << (i % 8)) != 0;
		}
		Ok(Compact(ret))
	}
}

impl<T: Codec, L: Unsigned> Codec for VecArray<T, L> {
	type Size = Mul<<T as Codec>::Size, L>;
}

impl<T: Encode, L: Unsigned> Encode for VecArray<T, L> where
	VecArray<T, L>: Codec
{
	fn encode(&self) -> Vec<u8> {
		encode_list(&self)
	}
}

impl<T: Decode, L: Unsigned> Decode for VecArray<T, L> where
	VecArray<T, L>: Codec
{
	fn decode(value: &[u8]) -> Result<Self, Error> {
		let decoded = decode_list::<T>(value)?;

		VecArray::try_from(decoded).map_err(|_| Error::InvalidLength)
	}
}

impl Codec for H256 {
	type Size = <Compact<GenericArray<u8, typenum::U32>> as Codec>::Size;
}

impl Encode for H256 {
	fn encode(&self) -> Vec<u8> {
		CompactRef(GenericArray::<u8, typenum::U32>::from_slice(&self.0[..])).encode()
	}
}

impl Decode for H256 {
	fn decode(value: &[u8]) -> Result<Self, Error> {
		let decoded = Compact::<GenericArray<u8, typenum::U32>>::decode(value)?;
		Ok(H256::from_slice(decoded.0.as_slice()))
	}
}