//! Adapter for serde's DeserializeSeed trait.
use core::{marker::PhantomData, ops::ControlFlow};
use serde::{
de::{DeserializeSeed, 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 _,
};
pub enum Error<T> {
Pending(T),
Incomplete,
Custom,
}
#[cfg(feature = "std")]
impl<T> std::error::Error for Error<T> {}
impl<T> core::fmt::Debug for Error<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Pending(_) => write!(f, "Pending"),
Self::Incomplete => write!(f, "Incomplete"),
Self::Custom => write!(f, "Custom"),
}
}
}
pub struct Builder<'ctx, T: DeserializeSeed<'ctx>, E>(
Result<T::Value, Error<T>>,
PhantomData<fn() -> E>,
);
impl<'ctx, T: DeserializeSeed<'ctx>, E: Effect<'ctx, ControlFlow<(), ()>>> crate::Builder<'ctx, E>
for Builder<'ctx, T, E>
where
Self: AsVisitor<'ctx, E>,
{
type Error = Error<T>;
type Value = T::Value;
fn build<'a>(self) -> Result<Self::Value, Self::Error> where Self: 'a {
self.0
}
type Seed = T;
fn from_seed(seed: Self::Seed) -> Self {
Self(Err(Error::Pending(seed)), PhantomData)
}
type Effect = SyncEffect;
}
impl<'ctx, T: DeserializeSeed<'ctx>> AsVisitor<'ctx, SyncEffect> for Builder<'ctx, T, SyncEffect> {
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
self
}
}
impl<'ctx, T: DeserializeSeed<'ctx> + Send> AsVisitor<'ctx, AsyncEffect>
for Builder<'ctx, T, AsyncEffect>
where
T::Value: Send,
{
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncEffect> {
self
}
}
any_trait! {
impl['a, 'ctx, T: DeserializeSeed<'ctx>, E] Builder<'ctx, T, E> = [
dyn Value<'ctx, OwnedStatic<bool>, SyncEffect> + 'a,
dyn Sequence<'ctx, SyncEffect> + 'a,
]
}
enum InjectedValue<'a, 'ctx, T> {
Bool(bool),
Sequence(&'a mut dyn SequenceScope<'ctx, SyncEffect>),
Extra(PhantomData<T>),
}
impl<'ctx, T: DeserializeSeed<'ctx>, E> Value<'ctx, OwnedStatic<bool>, SyncEffect> for Builder<'ctx, T, E> {
#[inline]
fn visit<'a>(
&'a mut self,
OwnedStatic(bool_value): OwnedStatic<bool>,
) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
where
'ctx: 'a,
{
let pending = core::mem::replace(&mut self.0, Err(Error::Incomplete));
let Err(Error::Pending(value)) = pending else {
todo!()
};
self.0 = value.deserialize(InjectedValue::Bool(bool_value));
if self.0.is_err() {
ControlFlow::Break(())
} else {
ControlFlow::Continue(())
}
}
}
impl<'ctx, T: DeserializeSeed<'ctx>, E> Sequence<'ctx, SyncEffect> for Builder<'ctx, T, E> {
#[inline]
fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx, SyncEffect>) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
where
'ctx: 'a,
{
let pending = core::mem::replace(&mut self.0, Err(Error::Incomplete));
let Err(Error::Pending(value)) = pending else {
todo!()
};
self.0 = value.deserialize(InjectedValue::Sequence(scope));
if self.0.is_err() {
ControlFlow::Break(())
} else {
ControlFlow::Continue(())
}
}
}
impl<T> core::fmt::Display for Error<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:?}", self)
}
}
impl<T> serde::de::Error for Error<T> {
fn custom<U>(_msg: U) -> Self
where
U: core::fmt::Display,
{
Error::Custom
}
}
impl<'a, 'ctx, T> Deserializer<'ctx> for InjectedValue<'a, 'ctx, T> {
type Error = Error<T>;
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, PhantomData)),
InjectedValue::Extra(_) => unreachable!(),
}
}
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, T>(&'a mut dyn SequenceScope<'ctx, SyncEffect>, PhantomData<T>);
impl<'a, 'ctx, T> SeqAccess<'ctx> for SequenceAccess<'a, 'ctx, T> {
type Error = Error<T>;
fn next_element_seed<U>(&mut self, seed: U) -> Result<Option<U::Value>, Self::Error>
where
U: serde::de::DeserializeSeed<'ctx>,
{
let mut builder = 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.
}
}
}