use crate::codec::{Codec, LowerHex};
use crate::{ByteArray, ByteBuf, Bytes};
use core::convert::TryInto;
use core::fmt;
use core::marker::PhantomData;
use serde::de::{Error, SeqAccess, Visitor};
use serde::Deserializer;
use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::string::String;
use alloc::vec::Vec;
use core::cmp;
pub(crate) fn decode_str<'de, C, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
C: Codec,
D: Deserializer<'de>,
{
let s: String = serde::Deserialize::deserialize(deserializer)?;
C::decode(&s)
}
pub trait Deserialize<'de, C: Codec = LowerHex>: Sized {
#[allow(missing_docs)]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>;
}
impl<'de: 'a, 'a, C: Codec> Deserialize<'de, C> for &'a [u8] {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
Err(D::Error::custom(
"human readable mode is not supported for &[u8]",
))
} else {
serde::Deserialize::deserialize(deserializer)
}
}
}
impl<'de, C: Codec> Deserialize<'de, C> for Vec<u8> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
decode_str::<C, _>(deserializer)
} else {
<ByteBuf as Deserialize<'de, C>>::deserialize(deserializer).map(ByteBuf::into_vec)
}
}
}
impl<'de: 'a, 'a, C: Codec> Deserialize<'de, C> for &'a Bytes {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
Err(D::Error::custom(
"human readable mode is not supported for &Bytes",
))
} else {
serde::Deserialize::deserialize(deserializer).map(Bytes::new)
}
}
}
impl<'de, C: Codec, const N: usize> Deserialize<'de, C> for [u8; N] {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
decode_str::<C, _>(deserializer)?
.try_into()
.map_err(|_| D::Error::custom("invalid array length"))
} else {
let arr: ByteArray<N> = serde::Deserialize::deserialize(deserializer)?;
Ok(*arr)
}
}
}
impl<'de, C: Codec, const N: usize> Deserialize<'de, C> for &'de [u8; N] {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
Err(D::Error::custom(
"human readable mode is not supported for &[u8; N]",
))
} else {
let arr: &ByteArray<N> = serde::Deserialize::deserialize(deserializer)?;
Ok(arr)
}
}
}
impl<'de, C: Codec, const N: usize> Deserialize<'de, C> for ByteArray<N> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
decode_str::<C, _>(deserializer)?
.try_into()
.map(ByteArray::new)
.map_err(|_| D::Error::custom("invalid array length"))
} else {
serde::Deserialize::deserialize(deserializer)
}
}
}
impl<'de: 'a, 'a, C: Codec, const N: usize> Deserialize<'de, C> for &'a ByteArray<N> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
Err(D::Error::custom(
"human readable mode is not supported for &ByteArray<N>",
))
} else {
serde::Deserialize::deserialize(deserializer)
}
}
}
impl<'de, C: Codec> Deserialize<'de, C> for ByteBuf {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
decode_str::<C, _>(deserializer).map(ByteBuf::from)
} else {
serde::Deserialize::deserialize(deserializer)
}
}
}
impl<'de: 'a, 'a, C: Codec> Deserialize<'de, C> for Cow<'a, [u8]> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct CowVisitor;
impl<'de> Visitor<'de> for CowVisitor {
type Value = Cow<'de, [u8]>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a byte array")
}
fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Borrowed(v))
}
fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Borrowed(v.as_bytes()))
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Owned(v.to_vec()))
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Owned(v.as_bytes().to_vec()))
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Owned(v))
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
Ok(Cow::Owned(v.into_bytes()))
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
let mut bytes = Vec::with_capacity(len);
while let Some(b) = visitor.next_element()? {
bytes.push(b);
}
Ok(Cow::Owned(bytes))
}
}
if deserializer.is_human_readable() {
decode_str::<C, _>(deserializer).map(Cow::Owned)
} else {
deserializer.deserialize_bytes(CowVisitor)
}
}
}
impl<'de: 'a, 'a, C: Codec> Deserialize<'de, C> for Cow<'a, Bytes> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
decode_str::<C, _>(deserializer)
.map(ByteBuf::from)
.map(Cow::Owned)
} else {
let cow: Cow<[u8]> = <Cow<[u8]> as Deserialize<'de, C>>::deserialize(deserializer)?;
match cow {
Cow::Borrowed(bytes) => Ok(Cow::Borrowed(Bytes::new(bytes))),
Cow::Owned(bytes) => Ok(Cow::Owned(ByteBuf::from(bytes))),
}
}
}
}
impl<'de, C: Codec> Deserialize<'de, C> for Box<[u8]> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
decode_str::<C, _>(deserializer).map(Vec::into_boxed_slice)
} else {
<Vec<u8> as Deserialize<'de, C>>::deserialize(deserializer).map(Vec::into_boxed_slice)
}
}
}
impl<'de, C: Codec> Deserialize<'de, C> for Box<Bytes> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
decode_str::<C, _>(deserializer)
.map(Vec::into_boxed_slice)
.map(Into::into)
} else {
let bytes: Box<[u8]> = <Box<[u8]> as Deserialize<'de, C>>::deserialize(deserializer)?;
Ok(bytes.into())
}
}
}
impl<'de, T, C: Codec> Deserialize<'de, C> for Option<T>
where
T: Deserialize<'de, C>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct BytesVisitor<T, C> {
out: PhantomData<(T, C)>,
}
impl<'de, T, C> Visitor<'de> for BytesVisitor<T, C>
where
T: Deserialize<'de, C>,
C: Codec,
{
type Value = Option<T>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("optional byte array")
}
fn visit_unit<E: Error>(self) -> Result<Self::Value, E> {
Ok(None)
}
fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
Ok(None)
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Some)
}
}
let visitor = BytesVisitor::<T, C> { out: PhantomData };
deserializer.deserialize_option(visitor)
}
}