solid-core 0.1.5

Core for the `solid` crate. Not intended to be used directly.
Documentation
use crate::{
    decode::Decode,
    encode::Encode,
    into_type::IntoType,
};
use std::borrow::Cow;

macro_rules! impl_encode_and_into_types_for_tuples {
	  ($(($index:tt => $ident:ident) ),+) => {
        #[allow(unused)]
        impl<$($ident: Encode, )+> Encode for ($($ident, )+) {
            fn encode(&self) -> Vec<u8> {
                let len = self.required_len();

                let mut buf: Vec<u8> = vec![0; len as usize];

                let mut count = 0usize;

                $(
                    count += if $ident::is_dynamic() { 1 } else { 1 };
                )+

                let mut offset: usize = count * 32;

                let mut index = 0;

                $(
                    let bytes = self.$index.encode();

                    if $ident::is_dynamic() {
                        buf[index * 32 + 24..(index + 1) * 32]
                            .copy_from_slice(&(offset as u64).to_be_bytes());
                        buf[offset..offset + bytes.len()]
                            .copy_from_slice(&bytes);
                        offset += bytes.len()
                    } else {
                        buf[index * 32..(index + 1) * 32]
                            .copy_from_slice(&bytes);
                    }

                    index += 1;
                )+

                buf
            }

            fn required_len(&self) -> u64 {
                let mut len = 0u64;

                $(
                    len += self.$index.required_len();
                    len += if $ident::is_dynamic() {
                        32
                    } else {
                        0
                    };
                )+

                len
            }

            fn is_dynamic() -> bool {
                true
            }
        }

        impl<$($ident: IntoType, )+> IntoType for ($($ident,) +) {
            fn into_type() -> Cow<'static, str> {
                let mut ty = Vec::new();
                $(
                    ty.push($ident::into_type());
                )+

                Cow::Owned(format!("({})", ty.join(",")))
            }
        }

        #[allow(unused)]
        impl<'a, $($ident: Encode + Decode<'a>, )+> Decode<'a> for ($($ident,) +)
        {
            fn decode(buf: &'a [u8]) -> Self {
                let mut index = 0;


                (
                    $(
                        {
                            let value = if $ident::is_dynamic() {
                                $ident::decode(&buf[index * 32..(index + 1) * 32])
                            } else {
                                let offset = u64::decode(&buf[index * 32..(index + 1) * 32]);
                                $ident::decode(&buf[offset as usize..])
                            };
                            index += 1;
                            value
                        },
                    )+
                )
            }
        }
	  };
}

impl_encode_and_into_types_for_tuples!(
    (0 => T0),
    (1 => T1)
);
impl_encode_and_into_types_for_tuples!(
    (0 => T0),
    (1 => T1),
    (2 => T2)
);

impl_encode_and_into_types_for_tuples!(
    (0 => T0),
    (1 => T1),
    (2 => T2),
    (3 => T3)
);

impl_encode_and_into_types_for_tuples!(
    (0 => T0),
    (1 => T1),
    (2 => T2),
    (3 => T3),
    (4 => T4)
);

impl_encode_and_into_types_for_tuples!(
    (0 => T0),
    (1 => T1),
    (2 => T2),
    (3 => T3),
    (4 => T4),
    (5 => T5)
);

impl_encode_and_into_types_for_tuples!(
    (0 => T0),
    (1 => T1),
    (2 => T2),
    (3 => T3),
    (4 => T4),
    (5 => T5),
    (6 => T6)
);