use std::{collections::VecDeque, ops::ControlFlow};
use treaty::{
any::{any_trait, static_wrapper::OwnedStatic},
build, build_with,
builders::core::array,
into_walker,
protocol::{
visitor::{Sequence, SequenceScope, Value},
ControlFlowFor, SyncEffect, Visitor,
},
Builder, Walk, Walker,
};
#[test]
fn demo() {
let a = Data::Sequence(vec![
Data::Bool(true),
Data::Sequence(vec![Data::Bool(false), Data::Bool(true)]),
Data::Bool(false),
]);
dbg!(array_to_array2([true, false]));
dbg!(array_to_array([true, true]));
let s = build_with::<array::Builder<'_, JsonLike, 3>, _>(into_walker(&a)).unwrap();
dbg!(s);
use treaty::builders::serde::deserialize::Builder as SerdeBuilder;
let x = build_with::<SerdeBuilder<serde_json::Value>, _>(into_walker(&a)).unwrap();
dbg!(x);
// let s = build_with::<JsonLike, _>(into_walker(a)).unwrap();
todo!();
// assert_eq!(s, "[true,[false,true,],false,]");
}
#[inline(never)]
pub fn array_to_array(x: [bool; 2]) -> [bool; 2] {
build(into_walker(x)).unwrap()
}
#[inline(never)]
pub fn array_to_array2(x: [bool; 2]) -> [bool; 2] {
array_to_array(x)
}
#[derive(Debug)]
enum Data {
Bool(bool),
Sequence(Vec<Data>),
}
const _: () = {
struct Impl<'ctx>(&'ctx Data);
impl<'ctx> From<&'ctx Data> for Impl<'ctx> {
fn from(value: &'ctx Data) -> Self {
Self(value)
}
}
impl<'ctx> Walk<'ctx> for &'ctx Data {
type Walker = Impl<'ctx>;
}
impl<'ctx> Walker<'ctx> for Impl<'ctx> {
type Effect = SyncEffect;
type Error = ();
type Output = ();
fn walk<'a>(
self,
visitor: &'a mut Visitor<'a, 'ctx>,
) -> ControlFlowFor<'a, SyncEffect, Self::Error, Self::Output> {
match self.0 {
Data::Bool(value) => walk_bool(*value, visitor),
Data::Sequence(value) => walk_vec(value, visitor),
}
core::ops::ControlFlow::Continue(())
}
}
};
fn walk_bool(value: bool, visitor: &mut Visitor<'_, '_>) {
visitor
.upcast_mut::<dyn Value<OwnedStatic<bool>>>()
.unwrap()
.visit(OwnedStatic(value));
}
fn walk_vec<'a, 'ctx>(value: &'ctx [Data], visitor: &'a mut Visitor<'a, 'ctx>) {
struct Scope<'ctx>(VecDeque<&'ctx Data>);
impl<'ctx> SequenceScope<'ctx> for Scope<'ctx> {
fn next<'a>(
&'a mut self,
visitor: &'a mut Visitor<'a, 'ctx>,
) -> ControlFlowFor<'a, SyncEffect, treaty::protocol::visitor::Status> {
if let Some(value) = self.0.pop_front() {
into_walker(value).walk(visitor);
ControlFlow::Continue(treaty::protocol::visitor::Status::Continue)
} else {
ControlFlow::Continue(treaty::protocol::visitor::Status::Done)
}
}
}
let mut scope = Scope(value.into_iter().collect());
visitor
.upcast_mut::<dyn Sequence<'_>>()
.unwrap()
.visit(&mut scope);
}
#[derive(Default)]
struct JsonLike(String);
impl<'ctx> Builder<'ctx> for JsonLike {
type Error = ();
type Value = String;
fn as_visitor(&mut self) -> &mut Visitor<'_, 'ctx> {
self
}
fn build(self) -> Result<Self::Value, Self::Error> {
Ok(self.0)
}
type Seed = ();
fn from_seed(seed: Self::Seed) -> Self {
Self::default()
}
}
any_trait! {
impl['a, 'ctx] JsonLike = [
dyn Value<'a, OwnedStatic<bool>> + 'a,
dyn Sequence<'ctx> + 'a,
]
}
impl Value<'_, OwnedStatic<bool>> for JsonLike {
fn visit(&mut self, value: OwnedStatic<bool>) -> ControlFlowFor<'_> {
self.0.push_str(&format!("{}", value.0));
ControlFlow::Continue(())
}
}
impl<'ctx> Sequence<'ctx> for JsonLike {
fn visit<'a>(
&'a mut self,
scope: &'a mut dyn SequenceScope<'ctx>,
) -> ControlFlowFor<'a, SyncEffect> {
self.0.push_str("[");
while let ControlFlow::Continue(treaty::protocol::visitor::Status::Continue) =
scope.next(self)
{
self.0.push_str(",");
}
self.0.push_str("]");
ControlFlow::Continue(())
}
}