Diffstat (limited to 'tests/demo.rs')
| -rw-r--r-- | tests/demo.rs | 210 |
1 files changed, 75 insertions, 135 deletions
diff --git a/tests/demo.rs b/tests/demo.rs index 6875f89..6f3565b 100644 --- a/tests/demo.rs +++ b/tests/demo.rs @@ -1,10 +1,11 @@ -use std::any::TypeId; - -use uniserde::{ - impls::core::iterator::IterWalker, - protocol::{implementer, AnyImpl, Implementation, Implementer, ImplementerExt}, - protocols::{sequence, ControlFlow}, - transform, Build, Builder, WalkOnce, +use std::{any::TypeId, collections::VecDeque, ops::ControlFlow}; +use treaty::{ + any::{any_trait, static_wrapper::OwnedStatic}, + protocol::{ + visitor::{Sequence, SequenceScope, Value}, + Visitor, + }, + Builder, Walk, Walker, }; #[test] @@ -15,10 +16,9 @@ fn demo() { Data::Bool(false), ]); - // let mut builder = <Data as Build>::Builder::default(); - let mut builder = StringBuilder::default(); - a.walk_once(builder.as_visitor()); - dbg!(builder.build()); + let mut builder = JsonLike::default(); + <Data as Walk>::Walker::from(a).walk(builder.as_visitor()).unwrap(); + dbg!(builder.build().unwrap()); todo!() } @@ -29,167 +29,107 @@ enum Data { Sequence(Vec<Data>), } -impl<'ctx> WalkOnce<'ctx> for Data { - type Error = (); - - type Value = (); +const _: () = { + struct Impl(Data); - fn walk_once(self, visitor: &mut dyn Implementer<'ctx>) -> Result<Self::Value, Self::Error> { - match self { - Data::Bool(value) => value.walk_once(visitor), - Data::Sequence(list) => IterWalker::new(list).walk_once(visitor), + impl From<Data> for Impl { + fn from(value: Data) -> Self { + Self(value) } } -} -#[derive(Default)] -struct StringBuilder(String); - -impl<'ctx> Builder<'ctx> for StringBuilder { - type Error = (); - - type Value = String; - - fn as_visitor(&mut self) -> &mut dyn Implementer<'ctx> { - self + impl<'ctx> Walk<'ctx> for Data { + type Walker = Impl; } - fn build(self) -> Result<Self::Value, Self::Error> { - Ok(self.0) - } - - fn accepts(id: TypeId) -> bool { - id == TypeId::of::<uniserde::protocols::sequence::Sequence>() - || id == TypeId::of::<uniserde::protocols::bool::Bool>() - } -} + impl<'ctx> Walker<'ctx> for Impl { + type Error = (); -implementer! { - impl['ctx] StringBuilder = [sequence::Sequence, uniserde::protocols::bool::Bool]; -} + type Output = (); -impl<'ctx> uniserde::protocols::sequence::Object<'ctx> for StringBuilder { - fn visit( - &mut self, - accessor: &mut dyn sequence::Accessor<'ctx>, - ) -> uniserde::protocols::ControlFlow { - self.0.push('['); - loop { - if accessor.next(self) != uniserde::protocols::sequence::ControlFlow::Continue { - break; + fn walk(self, visitor: Visitor<'_, 'ctx>) -> Result<Self::Output, Self::Error> { + match self.0 { + Data::Bool(value) => walk_bool(value, visitor), + Data::Sequence(value) => walk_vec(value, visitor), } - self.0.push_str(", "); + Ok(()) } - self.0.push(']'); - uniserde::protocols::ControlFlow::Done - } -} - -impl<'ctx> uniserde::protocols::bool::Object<'ctx> for StringBuilder { - fn visit(&mut self, value: bool) -> ControlFlow { - self.0.push_str(&value.to_string()); - ControlFlow::Done } -} - -#[derive(Default)] -enum DataBuilder { - #[default] - Empty, - Bool(<bool as Build<'static>>::Builder), - Sequence(VecBuilder<Data>), -} +}; -impl<'ctx> Build<'ctx> for Data { - type Builder = DataBuilder; +fn walk_bool(value: bool, visitor: Visitor<'_, '_>) { + visitor + .upcast_mut::<dyn Value<OwnedStatic<bool>>>() + .unwrap() + .visit(OwnedStatic(value)); } -impl<'ctx> Builder<'ctx> for DataBuilder { - type Error = (); - - type Value = Data; +fn walk_vec(value: Vec<Data>, visitor: Visitor<'_, '_>) { + struct Scope(VecDeque<Data>); - fn as_visitor(&mut self) -> &mut dyn Implementer<'ctx> { - self - } + impl<'ctx> SequenceScope<'ctx> for Scope { + fn next( + &mut self, + visitor: Visitor<'_, 'ctx>, + ) -> treaty::protocol::ControlFlow<(), treaty::protocol::visitor::Status> { + if let Some(value) = self.0.pop_front() { + <<Data as Walk>::Walker>::from(value).walk(visitor).unwrap(); - fn build(self) -> Result<Self::Value, Self::Error> { - match self { - DataBuilder::Empty => Err(()), - DataBuilder::Bool(value) => Ok(Data::Bool(value.build().unwrap())), - DataBuilder::Sequence(list) => Ok(Data::Sequence(list.build().unwrap())), + ControlFlow::Continue(treaty::protocol::visitor::Status::Continue) + } else { + ControlFlow::Continue(treaty::protocol::visitor::Status::Done) + } } } - fn accepts(id: TypeId) -> bool { - <<bool as Build>::Builder as Builder>::accepts(id) - || <VecBuilder<Data> as Builder>::accepts(id) - } -} - -impl<'ctx> Implementer<'ctx> for DataBuilder { - fn interface(&mut self, id: TypeId) -> Option<AnyImpl<'_, 'ctx>> { - if <<bool as Build>::Builder as Builder>::accepts(id) { - let builder = <<bool as Build>::Builder as Default>::default(); - *self = Self::Bool(builder); - } else if VecBuilder::<Data>::accepts(id) { - let builder = VecBuilder::<Data>::default(); - *self = Self::Sequence(builder); - } + let mut scope = Scope(value.into()); - match self { - DataBuilder::Empty => panic!(), - DataBuilder::Bool(builder) => builder.interface(id), - DataBuilder::Sequence(builder) => builder.interface(id), - } - } + visitor + .upcast_mut::<dyn Sequence<'_>>() + .unwrap() + .visit(&mut scope); } -struct VecBuilder<T>(Vec<T>); - -impl<T> Default for VecBuilder<T> { - fn default() -> Self { - Self(Vec::new()) - } -} +#[derive(Default)] +struct JsonLike(String); -impl<'ctx, T: Build<'ctx>> Builder<'ctx> for VecBuilder<T> { +impl<'ctx> Builder<'ctx> for JsonLike { type Error = (); - type Value = Vec<T>; + type Value = String; - fn as_visitor(&mut self) -> &mut dyn uniserde::protocol::Implementer<'ctx> { + fn as_visitor(&mut self) -> Visitor<'_, 'ctx> { self } fn build(self) -> Result<Self::Value, Self::Error> { Ok(self.0) } +} - fn accepts(id: TypeId) -> bool { - id == TypeId::of::<uniserde::protocols::sequence::Sequence>() - } +any_trait! { + impl['a, 'ctx] JsonLike = [ + dyn Value<OwnedStatic<bool>> + 'a, + dyn Sequence<'ctx> + 'a, + ]; } -implementer! { - impl['ctx, T: Build<'ctx>] VecBuilder<T> = [sequence::Sequence]; +impl Value<OwnedStatic<bool>> for JsonLike { + fn visit(&mut self, value: OwnedStatic<bool>) -> treaty::protocol::ControlFlow { + self.0.push_str(&format!("{}", value.0)); + ControlFlow::Continue(()) + } } -impl<'ctx, T: Build<'ctx>> sequence::Object<'ctx> for VecBuilder<T> { - fn visit( - &mut self, - accessor: &mut dyn sequence::Accessor<'ctx>, - ) -> uniserde::protocols::ControlFlow { - loop { - let mut builder = <T as Build>::Builder::default(); - let flow = accessor.next(builder.as_visitor()); - if flow == uniserde::protocols::sequence::ControlFlow::Done { - break; - } else { - let Ok(value) = builder.build() else { panic!() }; - self.0.push(value); - } +impl<'ctx> Sequence<'ctx> for JsonLike { + fn visit(&mut self, scope: &mut dyn SequenceScope<'ctx>) -> treaty::protocol::ControlFlow { + self.0.push_str("["); + while let ControlFlow::Continue(treaty::protocol::visitor::Status::Continue) = + scope.next(self) + { + self.0.push_str(","); } - ControlFlow::Done + self.0.push_str("]"); + ControlFlow::Continue(()) } } |