//! Adapter for serde's Deserialize trait.
use core::{marker::PhantomData, ops::ControlFlow};
use serde::{de::SeqAccess, forward_to_deserialize_any, Deserialize, Deserializer};
use crate::{
any::static_wrapper::OwnedStatic,
any_trait,
protocol::{
visitor::{Sequence, SequenceScope, Status, Value},
AsObj, AsyncEffect, Yield, Effect, SyncEffect,
},
AsVisitor, Builder as _,
};
#[derive(Debug)]
pub enum Error {
Incomplete,
Custom,
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
pub struct Builder<T, E>(Result<T, Error>, PhantomData<fn() -> E>);
impl<'ctx, T: Deserialize<'ctx>, E: Effect<'ctx, ControlFlow<(), ()>>> crate::Builder<'ctx, E> for Builder<T, E>
where
Self: AsVisitor<'ctx, E>,
{
type Error = Error;
type Value = T;
fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
self.0
}
type Seed = ();
fn from_seed(seed: Self::Seed) -> Self {
Self(Err(Error::Incomplete), PhantomData)
}
type Effect = SyncEffect;
}
impl<'ctx, T: Deserialize<'ctx>> AsVisitor<'ctx, SyncEffect> for Builder<T, SyncEffect> {
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
self
}
}
impl<'ctx, T: Deserialize<'ctx> + Send> AsVisitor<'ctx, AsyncEffect> for Builder<T, AsyncEffect> {
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncEffect> {
self
}
}
any_trait! {
impl['a, 'ctx, T: Deserialize<'ctx>, E] Builder<T, E> = [
dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
dyn Sequence<'ctx, SyncEffect> + 'a,
]
}
enum InjectedValue<'a, 'ctx> {
Bool(bool),
Sequence(&'a mut dyn SequenceScope<'ctx, SyncEffect>),
}
impl<'ctx, T: Deserialize<'ctx>, E> Value<'ctx, OwnedStatic<bool>, SyncEffect> for Builder<T, E> {
#[inline]
fn visit<'a>(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
where
'ctx: 'a,
{
self.0 = T::deserialize(InjectedValue::Bool(value));
if self.0.is_err() {
ControlFlow::Break(())
} else {
ControlFlow::Continue(())
}
}
}
impl<'ctx, T: Deserialize<'ctx>, E> Sequence<'ctx, SyncEffect> for Builder<T, E> {
#[inline]
fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
where
'ctx: 'a,
{
self.0 = T::deserialize(InjectedValue::Sequence(scope));
if self.0.is_err() {
ControlFlow::Break(())
} else {
ControlFlow::Continue(())
}
}
}
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}", self)
}
}
impl serde::de::Error for Error {
fn custom<T>(_msg: T) -> Self
where
T: core::fmt::Display,
{
Error::Custom
}
}
impl<'a, 'ctx> Deserializer<'ctx> for InjectedValue<'a, 'ctx> {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'ctx>,
{
match self {
InjectedValue::Bool(value) => visitor.visit_bool(value),
InjectedValue::Sequence(scope) => visitor.visit_seq(SequenceAccess(scope)),
}
}
forward_to_deserialize_any! {
<W: Visitor<'ctx>>
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
}
struct SequenceAccess<'a, 'ctx>(&'a mut dyn SequenceScope<'ctx, SyncEffect>);
impl<'a, 'ctx> SeqAccess<'ctx> for SequenceAccess<'a, 'ctx> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: serde::de::DeserializeSeed<'ctx>,
{
let mut builder = super::deserialize_seed::Builder::<_, SyncEffect>::from_seed(seed);
match self.0.next(builder.as_visitor()) {
ControlFlow::Continue(Status::Continue) => match builder.build() {
Ok(value) => Ok(Some(value)),
Err(error) => Err(Error::Incomplete),
},
ControlFlow::Continue(Status::Done) => Ok(None),
ControlFlow::Break(()) => Err(Error::Incomplete), // use the one from builder
// if any.
}
}
}