use crate::{Vec, visitor::FixedBytesVisitor};
use serde::{de, de::Error, ser, ser::SerializeSeq};
pub fn serialize<S: serde::ser::Serializer, T: AsRef<[u8]>>(
value: &T,
serializer: S,
) -> core::result::Result<S::Ok, S::Error> {
serializer.serialize_bytes(value.as_ref())
}
pub fn deserialize<'de, D: serde::de::Deserializer<'de>, T: TryFrom<Vec<u8>>>(
deserializer: D,
) -> core::result::Result<T, D::Error> {
deserializer.deserialize_tuple(core::mem::size_of::<T>(), FixedBytesVisitor::<T>::new())
}
pub mod array {
use super::*;
use core::fmt;
pub fn serialize<S: ser::Serializer, T: AsRef<[u8]>>(
value: &[T],
serializer: S,
) -> core::result::Result<S::Ok, S::Error> {
let mut seq = serializer.serialize_seq(Some(value.len()))?;
for item in value {
seq.serialize_element(item.as_ref())?;
}
seq.end()
}
pub fn deserialize<'de, D: de::Deserializer<'de>, T: TryFrom<Vec<u8>>>(
deserializer: D,
) -> core::result::Result<Vec<T>, D::Error> {
deserializer.deserialize_seq(FixedArrayVisitor::<T>::new())
}
#[derive(Default)]
struct FixedArrayVisitor<T: TryFrom<Vec<u8>>> {
_marker: core::marker::PhantomData<T>,
}
impl<T: TryFrom<Vec<u8>>> FixedArrayVisitor<T> {
fn new() -> Self {
Self {
_marker: core::marker::PhantomData,
}
}
}
impl<'de, T: TryFrom<Vec<u8>>> de::Visitor<'de> for FixedArrayVisitor<T> {
type Value = Vec<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence of fixed-size byte arrays")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: de::SeqAccess<'de>,
{
let mut result = Vec::new();
while let Some(bytes) = seq.next_element::<Vec<u8>>()? {
let item = T::try_from(bytes)
.map_err(|_| A::Error::custom("failed to convert bytes to fixed array"))?;
result.push(item);
}
Ok(result)
}
}
}