use std::ops::{Deref, DerefMut};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct U8Array<const N: usize>(pub [u8; N]);
impl<const N: usize> From<U8Array<N>> for sodoken::BufReadSized<N> {
fn from(o: U8Array<N>) -> Self {
o.0.into()
}
}
impl<const N: usize> From<[u8; N]> for U8Array<N> {
fn from(o: [u8; N]) -> Self {
Self(o)
}
}
impl<const N: usize> From<sodoken::BufReadSized<N>> for U8Array<N> {
fn from(o: sodoken::BufReadSized<N>) -> Self {
(*o.read_lock_sized()).into()
}
}
impl<const N: usize> From<Box<[u8]>> for U8Array<N> {
fn from(o: Box<[u8]>) -> Self {
assert_eq!(o.len(), N);
let mut out = [0; N];
out.copy_from_slice(&o[0..N]);
out.into()
}
}
impl<const N: usize> From<Vec<u8>> for U8Array<N> {
fn from(o: Vec<u8>) -> Self {
o.into_boxed_slice().into()
}
}
impl<const N: usize> Deref for U8Array<N> {
type Target = [u8; N];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<const N: usize> DerefMut for U8Array<N> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<const N: usize> AsRef<[u8; N]> for U8Array<N> {
fn as_ref(&self) -> &[u8; N] {
self.deref()
}
}
impl<const N: usize> AsMut<[u8; N]> for U8Array<N> {
fn as_mut(&mut self) -> &mut [u8; N] {
self.deref_mut()
}
}
impl<const N: usize> serde::Serialize for U8Array<N> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_bytes(self.deref())
}
}
impl<'de, const N: usize> serde::Deserialize<'de> for U8Array<N> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let v: rmpv::Value = serde::Deserialize::deserialize(deserializer)?;
let v = match v {
rmpv::Value::Binary(b) => b,
rmpv::Value::Ext(_, b) => b,
_ => {
return Err(serde::de::Error::custom(
"invalid type, expected bytes",
))
}
};
if v.len() != N {
return Err(serde::de::Error::custom(format!(
"expected {} bytes, got {} bytes",
N,
v.len()
)));
}
let mut out = [0; N];
out.copy_from_slice(&v[0..N]);
Ok(Self(out))
}
}