//! 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, effect::{AsObj, AsyncEffect, Effect, SyncEffect, Yield}, protocol::visitor::{Sequence, SequenceScope, Status, Value}, AsVisitor, Builder as _, }; pub enum Error { Pending(T), Incomplete, Custom, } #[cfg(feature = "std")] impl std::error::Error for Error {} impl core::fmt::Debug for Error { 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>, PhantomData 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; type Value = T::Value; fn build<'a>(self) -> Result 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<'a, 'ctx, OwnedStatic, SyncEffect> + 'a, dyn Sequence<'ctx, SyncEffect> + 'a, ] } enum InjectedValue<'a, 'ctx, T> { Bool(bool), Sequence(&'a mut dyn SequenceScope<'ctx, SyncEffect>), Extra(PhantomData), } impl<'a, 'ctx: 'a, T: DeserializeSeed<'ctx>, E> Value<'a, 'ctx, OwnedStatic, SyncEffect> for Builder<'ctx, T, E> { #[inline] fn visit( &'a mut self, OwnedStatic(bool_value): OwnedStatic, ) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect> { 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 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(_msg: U) -> Self where U: core::fmt::Display, { Error::Custom } } impl<'a, 'ctx, T> Deserializer<'ctx> for InjectedValue<'a, 'ctx, T> { type Error = Error; fn deserialize_any(self, visitor: V) -> Result 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! { > 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); impl<'a, 'ctx, T> SeqAccess<'ctx> for SequenceAccess<'a, 'ctx, T> { type Error = Error; fn next_element_seed(&mut self, seed: U) -> Result, 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. } } }