use core::convert::Infallible;
use crate::{NoParameters, Zeros};
pub trait ByteArray: private::Sealed {
fn new() -> Self;
fn as_ref(&self) -> &[u8];
fn as_mut(&mut self) -> &mut [u8];
}
mod private {
pub trait Sealed {}
impl<const LEN: usize> Sealed for [u8; LEN] {}
}
impl<const LEN: usize> ByteArray for [u8; LEN] {
#[inline]
fn new() -> Self {
[0; LEN]
}
#[inline]
fn as_ref(&self) -> &[u8] {
self
}
#[inline]
fn as_mut(&mut self) -> &mut [u8] {
self
}
}
pub trait FromByteArray: Sized {
type Error;
type Array: ByteArray;
fn from_bytes(bytes: Self::Array) -> Result<Self, Self::Error>;
}
impl FromByteArray for NoParameters {
type Error = Infallible;
type Array = [u8; 0];
fn from_bytes(_: Self::Array) -> Result<Self, Self::Error> {
Ok(Self {})
}
}
impl FromByteArray for u8 {
type Error = Infallible;
type Array = [u8; 1];
fn from_bytes(bytes: Self::Array) -> Result<Self, Self::Error> {
Ok(Self::from_be_bytes(bytes))
}
}
impl FromByteArray for u16 {
type Error = Infallible;
type Array = [u8; 2];
fn from_bytes(bytes: Self::Array) -> Result<Self, Self::Error> {
Ok(Self::from_be_bytes(bytes))
}
}
impl FromByteArray for u32 {
type Error = Infallible;
type Array = [u8; 4];
fn from_bytes(bytes: Self::Array) -> Result<Self, Self::Error> {
Ok(Self::from_be_bytes(bytes))
}
}
impl FromByteArray for u64 {
type Error = Infallible;
type Array = [u8; 8];
fn from_bytes(bytes: Self::Array) -> Result<Self, Self::Error> {
Ok(Self::from_be_bytes(bytes))
}
}
impl FromByteArray for u128 {
type Error = Infallible;
type Array = [u8; 16];
fn from_bytes(bytes: Self::Array) -> Result<Self, Self::Error> {
Ok(Self::from_be_bytes(bytes))
}
}
impl<const LEN: usize> FromByteArray for [u8; LEN] {
type Error = Infallible;
type Array = Self;
fn from_bytes(bytes: Self::Array) -> Result<Self, Self::Error> {
Ok(bytes)
}
}
#[cfg(feature = "packed_struct")]
impl<V, const LEN: usize> FromByteArray for V
where
V: packed_struct::PackedStruct<ByteArray = [u8; LEN]> + crate::Register,
{
type Error = packed_struct::PackingError;
type Array = [u8; LEN];
fn from_bytes(bytes: Self::Array) -> Result<Self, Self::Error> {
V::unpack(&bytes)
}
}
pub trait ToByteArray {
type Error;
type Array: ByteArray;
fn to_bytes(self) -> Result<Self::Array, Self::Error>;
}
impl ToByteArray for NoParameters {
type Error = Infallible;
type Array = [u8; 0];
fn to_bytes(self) -> Result<Self::Array, Self::Error> {
Ok([])
}
}
impl<const LEN: usize> ToByteArray for Zeros<LEN> {
type Error = Infallible;
type Array = [u8; LEN];
fn to_bytes(self) -> Result<Self::Array, Self::Error> {
Ok([0; LEN])
}
}
impl ToByteArray for u8 {
type Error = Infallible;
type Array = [u8; 1];
fn to_bytes(self) -> Result<Self::Array, Self::Error> {
Ok([self])
}
}
impl ToByteArray for u16 {
type Error = Infallible;
type Array = [u8; 2];
fn to_bytes(self) -> Result<Self::Array, Self::Error> {
Ok(self.to_be_bytes())
}
}
impl ToByteArray for u32 {
type Error = Infallible;
type Array = [u8; 4];
fn to_bytes(self) -> Result<Self::Array, Self::Error> {
Ok(self.to_be_bytes())
}
}
impl ToByteArray for u64 {
type Error = Infallible;
type Array = [u8; 8];
fn to_bytes(self) -> Result<Self::Array, Self::Error> {
Ok(self.to_be_bytes())
}
}
impl ToByteArray for u128 {
type Error = Infallible;
type Array = [u8; 16];
fn to_bytes(self) -> Result<Self::Array, Self::Error> {
Ok(self.to_be_bytes())
}
}
impl<const LEN: usize> ToByteArray for [u8; LEN] {
type Error = Infallible;
type Array = Self;
fn to_bytes(self) -> Result<Self::Array, Self::Error> {
Ok(self)
}
}
#[cfg(feature = "packed_struct")]
impl<V, const LEN: usize> ToByteArray for V
where
V: packed_struct::PackedStruct<ByteArray = [u8; LEN]> + crate::Register,
{
type Error = packed_struct::PackingError;
type Array = [u8; LEN];
fn to_bytes(self) -> Result<Self::Array, Self::Error> {
self.pack()
}
}