Diffstat (limited to 'src/walk/walkers/serde/deserializer.rs')
| -rw-r--r-- | src/walk/walkers/serde/deserializer.rs | 202 |
1 files changed, 155 insertions, 47 deletions
diff --git a/src/walk/walkers/serde/deserializer.rs b/src/walk/walkers/serde/deserializer.rs index 8818102..32e58f1 100644 --- a/src/walk/walkers/serde/deserializer.rs +++ b/src/walk/walkers/serde/deserializer.rs @@ -1,11 +1,15 @@ +use crate::walkers::core::noop::NoopWalker; use effectful::{ - bound::{Dynamic, No}, + bound::{Dynamic, HasSendAndSync, No}, effective::Effective, effective::NativeEffective, environment::{DynBind, EnvConfig, Environment, NativeForm}, SendSync, }; -use serde::{de::MapAccess, Deserializer}; +use serde::{ + de::{DeserializeSeed, MapAccess}, + Deserializer, +}; use crate::{ any::{BorrowedStaticHrt, OwnedStatic, TempBorrowedStatic, TempBorrowedStaticHrt, TypeName}, @@ -13,8 +17,8 @@ use crate::{ hkt::Marker, protocol::{ visitor::{ - request_hint, tags, visit_sequence, visit_value, EffectiveVisitExt as _, SequenceScope, - TagConst, TagKnown, TagProto, ValueKnown, ValueProto, VisitResult, + request_hint, tags, visit_sequence, visit_tag, visit_value, EffectiveVisitExt as _, + SequenceScope, TagConst, TagKnown, TagProto, ValueKnown, ValueProto, VisitResult, }, walker::hint::{DynVisitorWith, Hint, HintMeta, HintProto, MetaHint, MetaKnown}, DynVisitor, DynWalker, @@ -69,19 +73,19 @@ where { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match &self.inner { - VisitorError::u8(err) => write!(f, "{}", err), - VisitorError::u16(err) => write!(f, "{}", err), - VisitorError::u32(err) => write!(f, "{}", err), - VisitorError::u64(err) => write!(f, "{}", err), - VisitorError::u128(err) => write!(f, "{}", err), - VisitorError::usize(err) => write!(f, "{}", err), - VisitorError::i8(err) => write!(f, "{}", err), - VisitorError::i16(err) => write!(f, "{}", err), - VisitorError::i32(err) => write!(f, "{}", err), - VisitorError::i64(err) => write!(f, "{}", err), - VisitorError::i128(err) => write!(f, "{}", err), - VisitorError::isize(err) => write!(f, "{}", err), - VisitorError::Serde(err) => write!(f, "{}", err.0), + VisitorError::u8(err) => write!(f, "u8 {}", err), + VisitorError::u16(err) => write!(f, "u16 {}", err), + VisitorError::u32(err) => write!(f, "u32 {}", err), + VisitorError::u64(err) => write!(f, "u64 {}", err), + VisitorError::u128(err) => write!(f, "u128 {}", err), + VisitorError::usize(err) => write!(f, "usize {}", err), + VisitorError::i8(err) => write!(f, "i8 {}", err), + VisitorError::i16(err) => write!(f, "i16 {}", err), + VisitorError::i32(err) => write!(f, "i32 {}", err), + VisitorError::i64(err) => write!(f, "i64 {}", err), + VisitorError::i128(err) => write!(f, "i128 {}", err), + VisitorError::isize(err) => write!(f, "isize {}", err), + VisitorError::Serde(err) => write!(f, "Serde {}", err.0), } } } @@ -97,7 +101,7 @@ where impl<'ctx, T, E: Environment> Walker<'ctx, E> for DeserializerWalker<'ctx, T, E> where - T: Deserializer<'ctx> + 'ctx, + T: Deserializer<'ctx>, E: EnvConfig<NeedSend = No, NeedSync = No>, { type Error = DeserializerWalkerError<'ctx, T>; @@ -120,8 +124,9 @@ where .cast() }) .if_not_finished((), |_, (this, visitor)| { - this.call_deserialize(|deserializer| { - deserializer.deserialize_any(Visitor::<T, E>::new(visitor.cast(), "any")) + this.call_deserialize(visitor.cast(), |visitor, deserializer| { + let x = deserializer.deserialize_any(Visitor::<T, E>::new(visitor, "any")); + x.map(|x| x.cast()) }) .cast() }) @@ -138,41 +143,48 @@ where any_trait! { impl['ctx, T][E] DeserializerWalker<'ctx, T, E> = [ HintProto<ValueProto<OwnedStatic<bool>, E>>, - HintProto<ValueProto<OwnedStatic<i8>, E>>, - HintProto<ValueProto<OwnedStatic<i16>, E>>, - HintProto<ValueProto<OwnedStatic<i32>, E>>, - HintProto<ValueProto<OwnedStatic<i64>, E>>, - HintProto<ValueProto<OwnedStatic<i128>, E>>, - HintProto<ValueProto<OwnedStatic<u8>, E>>, - HintProto<ValueProto<OwnedStatic<u16>, E>>, - HintProto<ValueProto<OwnedStatic<u32>, E>>, - HintProto<ValueProto<OwnedStatic<u64>, E>>, - HintProto<ValueProto<OwnedStatic<u128>, E>>, - HintProto<ValueProto<OwnedStatic<char>, E>>, - HintProto<TagProto<tags::Map, E>>, + // HintProto<ValueProto<OwnedStatic<i8>, E>>, + // HintProto<ValueProto<OwnedStatic<i16>, E>>, + // HintProto<ValueProto<OwnedStatic<i32>, E>>, + // HintProto<ValueProto<OwnedStatic<i64>, E>>, + // HintProto<ValueProto<OwnedStatic<i128>, E>>, + // HintProto<ValueProto<OwnedStatic<u8>, E>>, + // HintProto<ValueProto<OwnedStatic<u16>, E>>, + // HintProto<ValueProto<OwnedStatic<u32>, E>>, + // HintProto<ValueProto<OwnedStatic<u64>, E>>, + // HintProto<ValueProto<OwnedStatic<u128>, E>>, + // HintProto<ValueProto<OwnedStatic<char>, E>>, + // HintProto<TagProto<tags::Map, E>>, ] where - T: Deserializer<'ctx> + 'ctx, + T: Deserializer<'ctx>, E: Environment<NeedSend = No, NeedSync = No> } impl<'ctx, T, E: Environment> DeserializerWalker<'ctx, T, E> where - T: Deserializer<'ctx> + 'ctx, + T: Deserializer<'ctx>, E: EnvConfig<NeedSend = No, NeedSync = No>, { - fn call_deserialize<'visitor: 'e, 'e, F>(&'e mut self, f: F) -> NativeForm<'e, VisitResult, E> - where - 'ctx: 'visitor, - F: FnOnce( + fn call_deserialize<'this: 'e, 'e, Cap>( + &'this mut self, + cap: Cap, + f: fn( + Cap, T, ) -> Result< - NativeForm<'visitor, (Option<VisitorError<'ctx, T>>, VisitResult), E>, + NativeForm<'e, (Option<VisitorError<'ctx, T>>, VisitResult), E, (&'ctx (), Cap)>, T::Error, >, + ) -> NativeForm<'e, VisitResult, E> + where + 'ctx: 'this, + Cap: DynBind<E> + 'e, { match core::mem::replace(&mut self.inner, Inner::Temp) { Inner::Init(deserializer) => { - match f(deserializer.0) { + // E::value(cap) + // .update((HasSendAndSync(f), self, deserializer), |(HasSendAndSync(f), this, deserializer), cap| { + match f(cap, deserializer.0) { Ok(eff) => eff .map(self, |this, result| match result { (None, result) => { @@ -185,7 +197,7 @@ where Flow::Err.into() } }) - .cast::<()>(), + .cast(), Err(err) => { self.inner = Inner::Error(DeserializerWalkerError { inner: VisitorError::Serde(Dynamic(err)), @@ -193,6 +205,9 @@ where E::value(Flow::Err.into()).cast() } } + // }) + // .map((), |_, (_, x)| x) + // .cast() } inner => { // We really shouldn't be in this situation... @@ -207,7 +222,7 @@ macro_rules! impl_hints { (<$ctx:lifetime, $T:ident, $E:ident> $($proto:ty => $method:ident: $type:ty),* $(,)?) => { $(impl<$ctx, $T, $E: Environment> Hint<$ctx, $proto> for DeserializerWalker<$ctx, $T, $E> where - $T: Deserializer<$ctx> + $ctx, + $T: Deserializer<$ctx>, $E: EnvConfig<NeedSend = No, NeedSync = No> { fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( @@ -218,7 +233,16 @@ macro_rules! impl_hints { where $ctx: 'this + 'visitor + 'hint + 'e, { - self.call_deserialize(|deserializer| deserializer.$method(Visitor::<$T, $E>::new(visitor.into_inner(), stringify!($type)))) + $E::value((self, visitor)) + .update((), |_, (this, visitor)| { + this.call_deserialize(visitor, move |visitor, deserializer| { + let x = deserializer.$method(Visitor::<$T, $E>::new(visitor.cast(), stringify!($type))); + x.map(|x| x.cast()) + }) + .cast() + }) + .map((), |_, (_, x)| x) + .cast() } fn known<'a>( @@ -258,7 +282,7 @@ impl_hints! { impl<'ctx, T, E: Environment> Hint<'ctx, TagProto<tags::Map, E>> for DeserializerWalker<'ctx, T, E> where - T: Deserializer<'ctx> + 'ctx, + T: Deserializer<'ctx>, E: EnvConfig<NeedSend = No, NeedSync = No>, { fn hint<'this: 'e, 'visitor: 'e, 'hint: 'e, 'e>( @@ -399,10 +423,13 @@ where A: MapAccess<'ctx>, { E::value((self, MapScope { map: Dynamic(map) })).update((), |_, (this, scope)| { + // Need to notify the visitor we are doing a map instead of just a sequence. + visit_tag::<tags::Map, E, _>(TagConst, this.visitor.cast(), NoopWalker::new()); + visit_sequence(this.visitor.cast(), scope).cast() }); - todo!() + Ok(E::value((None, VisitResult::Control(Flow::Done))).cast()) } } @@ -422,11 +449,92 @@ where fn next<'a: 'c, 'b: 'c, 'c>( &'a mut self, - visitor: DynVisitor<'b, 'ctx, E>, + mut visitor: DynVisitor<'b, 'ctx, E>, ) -> NativeForm<'c, Flow, E> where 'ctx: 'c + 'a + 'b, { - todo!() + // need to convert visitor into a serde key and value deserializer + // match self.map.0.next_entry() { + // Ok(Some((key, value))) => {}, + // Ok(None) => {}, + // Err(err) => {}, + // } + + // let key = self.map.0.next_key(); // assume we have done this + // let value = self.map.0.next_value_seed(()); // we want value here to be an + // effective. + let x = self.map.0.next_key_seed(KeyDeserialize { + visitor: visitor.cast(), + }); + // dbg!(&x); + + if x.unwrap().is_some() { + // There is another item. + let x = self.map.0.next_value_seed(ValueDeserialize { visitor }); + // dbg!(x); + E::value(Flow::Continue).cast() + } else { + E::value(Flow::Done).cast() + } + } +} + +struct KeyDeserialize<'a, 'ctx, E: Environment> { + visitor: DynVisitor<'a, 'ctx, E>, +} + +impl<'a, 'ctx: 'a, E: Environment> DeserializeSeed<'ctx> for KeyDeserialize<'a, 'ctx, E> +where + E: EnvConfig<NeedSend = No, NeedSync = No>, +{ + type Value = (); + + fn deserialize<D>(mut self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'ctx>, + { + // We have a deserializer and we know how to handle those! + let walker = DeserializerWalker::<'_, _, E>::new(deserializer); + + // We can't return an effective that stores D as we don't know D's lifetime, + // so we must block instead. This should be fine as serde itself isn't async + // normally. + + let x = visit_tag::<tags::Key, E, _>(TagConst, self.visitor.cast(), walker) + .map((), |_, result| match result { + Ok(visit) => visit.unit_skipped(), + Err(_) => Flow::Err.into(), + }) + .wait(); + + // dbg!(x); + + Ok(()) + } +} + +struct ValueDeserialize<'a, 'ctx, E: Environment> { + visitor: DynVisitor<'a, 'ctx, E>, +} + +impl<'a, 'ctx, E: Environment> DeserializeSeed<'ctx> for ValueDeserialize<'a, 'ctx, E> +where + E: EnvConfig<NeedSend = No, NeedSync = No>, +{ + type Value = (); + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: Deserializer<'ctx>, + { + // We have a deserializer and we know how to handle those! + let walker = DeserializerWalker::<'_, _, E>::new(deserializer); + + let x = walker.walk(self.visitor).wait(); + + dbg!(x); + + Ok(()) } } |