serde_sv2 2.0.1

Serlializer and Deserializer for Stratum V2 data format
Documentation
use crate::{error::Error, primitives::FixedSize};
use alloc::boxed::Box;
use core::convert::TryFrom;
use serde::{de::Visitor, ser, Deserialize, Deserializer, Serialize};

#[derive(Debug, PartialEq, Clone)]
enum Inner<'a> {
    Ref(&'a [u8]),
    Owned(Box<[u8; 64]>),
}

#[derive(Debug, PartialEq, Clone)]
pub struct Signature<'u>(Inner<'u>);

impl<'u> TryFrom<&'u [u8]> for Signature<'u> {
    type Error = Error;

    #[inline]
    fn try_from(v: &'u [u8]) -> core::result::Result<Self, Error> {
        if v.len() == 64 {
            Ok(Self(Inner::Ref(v)))
        } else {
            Err(Error::InvalidSignatureSize(v.len()))
        }
    }
}
impl<'u> TryFrom<&'u mut [u8]> for Signature<'u> {
    type Error = Error;

    #[inline]
    fn try_from(v: &'u mut [u8]) -> core::result::Result<Self, Error> {
        if v.len() == 64 {
            Ok(Self(Inner::Ref(v)))
        } else {
            Err(Error::InvalidSignatureSize(v.len()))
        }
    }
}

impl<'u> From<[u8; 64]> for Signature<'u> {
    fn from(v: [u8; 64]) -> Self {
        Signature(Inner::Owned(Box::new(v)))
    }
}

impl<'u> From<&'u Signature<'u>> for &'u [u8] {
    #[inline]
    fn from(v: &'u Signature<'u>) -> Self {
        match &v.0 {
            Inner::Ref(v) => v,
            Inner::Owned(v) => &v[..],
        }
    }
}

impl<'u> Serialize for Signature<'u> {
    #[inline]
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
    where
        S: ser::Serializer,
    {
        serializer.serialize_bytes(self.into())
    }
}

struct SignatureVisitor;

impl<'a> Visitor<'a> for SignatureVisitor {
    type Value = Signature<'a>;

    fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
        formatter.write_str("a 64 bytes unsigned le int")
    }

    #[inline]
    fn visit_borrowed_bytes<E>(self, value: &'a [u8]) -> Result<Self::Value, E> {
        Ok(Signature(Inner::Ref(value)))
    }
}

impl<'de: 'a, 'a> Deserialize<'de> for Signature<'a> {
    #[inline]
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        deserializer.deserialize_newtype_struct("Signature", SignatureVisitor)
    }
}

impl<'a> FixedSize for Signature<'a> {
    const FIXED_SIZE: usize = 64;
}