rac 1.3.4

Traits and types to work with elliptic curve
Documentation
use serde::{ser, de};
use generic_array::{GenericArray, ArrayLength, typenum};

pub type Array<N> = GenericArray<u8, N>;

pub trait LineValid
where
    Self: Sized,
{
    type Length: ArrayLength<u8>;

    fn try_clone_array(a: &Array<Self::Length>) -> Result<Self, ()>;
    fn clone_line(&self) -> Array<Self::Length>;
}

pub trait Line
where
    Self: LineValid,
{
    fn clone_array(a: &Array<Self::Length>) -> Self;
}

impl<L> LineValid for Array<L>
where
    L: ArrayLength<u8>,
{
    type Length = L;

    fn try_clone_array(a: &Array<Self::Length>) -> Result<Self, ()> {
        Ok(a.clone())
    }

    fn clone_line(&self) -> Array<Self::Length> {
        self.clone()
    }
}

impl<L> Line for Array<L>
where
    L: ArrayLength<u8>,
{
    fn clone_array(a: &Array<Self::Length>) -> Self {
        a.clone()
    }
}

impl LineValid for [u8; 0] {
    type Length = typenum::U0;

    fn try_clone_array(_a: &Array<Self::Length>) -> Result<Self, ()> {
        Ok([])
    }

    fn clone_line(&self) -> Array<Self::Length> {
        Array::default()
    }
}

impl Line for [u8; 0] {
    fn clone_array(_a: &Array<Self::Length>) -> Self {
        []
    }
}

pub struct LineLike<T>(pub T)
where
    T: Line;

impl<T> Clone for LineLike<T>
where
    T: Line,
{
    fn clone(&self) -> Self {
        let array = self.0.clone_line();
        LineLike(T::clone_array(&array))
    }
}

impl<T> ser::Serialize for LineLike<T>
where
    T: Line,
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        let array = self.0.clone_line();
        array.serialize(serializer)
    }
}

impl<'de, T> de::Deserialize<'de> for LineLike<T>
where
    T: Line,
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: de::Deserializer<'de>,
    {
        let array = de::Deserialize::deserialize(deserializer)?;
        Ok(LineLike(T::clone_array(&array)))
    }
}