use treaty::{
any::{OwnedStatic, TempBorrowedStatic},
builders::{self, core::r#struct::StructBuilder},
effect::{ErasedEffective, Effect, Effective},
protocol::{
visitor::{tags, visit_sequence, visit_tag, visit_value, TagConst, VisitResult},
DynVisitor,
},
transform,
walkers::{
self,
core::{
noop::NoopWalker,
r#struct::{StaticType, StructWalker},
},
},
Build, Builder, DefaultMode, Flow, Walk, Walker,
};
// use crate::common::{protocol::sequence::MockSequenceScope, walker::MockWalker};
//
// mod common;
#[derive(Debug, PartialEq)]
struct X {
a: bool,
b: bool,
}
struct Info;
impl<'ctx, M> walkers::core::r#struct::StructTypeInfo<'ctx, M> for Info {
const NAME: &'static str = "X";
const FIELDS: &'static [&'static str] = &["a", "b"];
type FieldError = ();
type S = StaticType;
type T = X;
#[inline(always)]
fn walk_field<'a, E: Effect>(
index: usize,
value: &'ctx Self::T,
visitor: DynVisitor<'a, 'ctx>,
) -> ErasedEffective<'a, Result<Flow, Self::FieldError>, E> {
todo!()
// E::wrap(async move {
// match index {
// 0 => {
// let walker = <&bool as Walk<M, E>>::into_walker(&value.a);
//
// assert_eq!(Walker::<E>::walk(walker, visitor).await, Ok(()));
//
// Ok(Flow::Continue)
// }
// 1 => {
// let walker = <&bool as Walk<M, E>>::into_walker(&value.b);
//
// assert_eq!(Walker::<E>::walk(walker, visitor).await, Ok(()));
//
// Ok(Flow::Continue)
// }
// _ => Ok(Flow::Done),
// }
// })
}
}
struct Fields<'ctx, M, E: Effect> {
a: <bool as Build<'ctx, M, E>>::Builder,
b: <bool as Build<'ctx, M, E>>::Builder,
}
#[derive(Copy, Clone, Debug)]
enum FieldMarker {
A,
B,
}
impl<'ctx, M, E: Effect> builders::core::r#struct::StructTypeInfo<'ctx, M, E> for Info {
type Builders = Fields<'ctx, M, E>;
type FieldMarker = FieldMarker;
type T = X;
#[inline(always)]
fn marker_from_index(index: usize) -> Option<Self::FieldMarker> {
match index {
0 => Some(FieldMarker::A),
1 => Some(FieldMarker::B),
_ => None,
}
}
#[inline(always)]
fn marker_from_name(name: &str) -> Option<Self::FieldMarker> {
match name {
"a" => Some(FieldMarker::A),
"b" => Some(FieldMarker::B),
_ => None,
}
}
type Error = ();
#[inline(always)]
fn from_builders<'a>(builders: Self::Builders) -> ErasedEffective<'a, Result<Self::T, Self::Error>, E> {
todo!()
// E::wrap(async {
// Ok(X {
// a: builders.a.build().await.unwrap(),
// b: builders.b.build().await.unwrap(),
// })
// })
}
#[inline(always)]
fn as_visitor<'a>(
marker: Self::FieldMarker,
builders: &'a mut Self::Builders,
) -> DynVisitor<'a, 'ctx> {
match marker {
FieldMarker::A => builders.a.as_visitor(),
FieldMarker::B => builders.b.as_visitor(),
}
}
type Seed = ();
#[inline(always)]
fn new_builders<'a>(_seed: Self::Seed) -> ErasedEffective<'a, Self::Builders, E> {
todo!()
// E::wrap(async {
// Fields {
// a: Builder::<E>::from_seed(()).await,
// b: Builder::<E>::from_seed(()).await,
// }
// })
}
}
// #[test]
// #[ignore]
// fn demo() {
// let value = X { a: true, b: false };
//
// let (other, _) = transform::<StructBuilder<Info, DefaultMode, _>, _, Blocking>(
// (),
// StructWalker::<Info, _, DefaultMode, _>::new(&value),
// )
// .value();
//
// assert_eq!(other.unwrap(), value);
// }
//
// #[test]
// fn from_basic_tuple_like() {
// // A tuple like is just a sequence.
// let mut scope = MockSequenceScope::<Blocking>::new();
//
// // First field.
// scope.expect_next().once().returning(|visitor| {
// // Visit a bool value.
// //
// // The bool visitor should report that it is done.
// assert_eq!(
// visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(),
// VisitResult::Control(Flow::Done)
// );
//
// // We have another field.
// Flow::Continue
// });
//
// // Second field.
// scope.expect_next().once().returning(|visitor| {
// // Visit a bool value.
// //
// // The bool visitor should report that it is done.
// assert_eq!(
// visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(),
// VisitResult::Control(Flow::Done)
// );
//
// // No more fields.
// Flow::Done
// });
//
// let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value();
// let visitor = builder.as_visitor();
//
// // Visit the sequence of field values.
// assert!(matches!(
// visit_sequence(visitor, &mut scope).value(),
// VisitResult::Control(Flow::Done)
// ));
//
// assert_eq!(builder.build().value().unwrap(), X { a: true, b: false });
// }
//
// #[test]
// fn from_basic_map_like() {
// // A map is built from a sequence.
// let mut scope = MockSequenceScope::<Blocking>::new();
//
// // Here we do the b field first to show a map-like doesn't care about order.
// scope.expect_next().once().returning(|mut visitor| {
// let mut walker = MockWalker::<(), ()>::new();
//
// // We need to give the b field name in the key tag.
// walker.expect_walk().once().returning(|visitor| {
// assert_eq!(
// visit_value::<_, Blocking>(visitor, TempBorrowedStatic("b")).value(),
// VisitResult::Control(Flow::Done)
// );
//
// Ok(())
// });
//
// // Tag the value with a key as the field name.
// assert_eq!(
// visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(),
// Ok(VisitResult::Control(Flow::Continue)),
// );
//
// // Visit the value as normal.
// assert_eq!(
// visit_value::<_, Blocking>(visitor, OwnedStatic(true)).value(),
// VisitResult::Control(Flow::Done)
// );
//
// // There is another field.
// Flow::Continue
// });
//
// // The other field.
// scope.expect_next().once().returning(|mut visitor| {
// let mut walker = MockWalker::<(), ()>::new();
//
// // Here we do field a.
// walker.expect_walk().once().returning(|visitor| {
// assert_eq!(
// visit_value::<_, Blocking>(visitor, TempBorrowedStatic("a")).value(),
// VisitResult::Control(Flow::Done)
// );
//
// Ok(())
// });
//
// // Tag the value with a key.
// assert_eq!(
// visit_tag::<tags::Key, Blocking, _>(TagConst, visitor.cast(), walker).value(),
// Ok(VisitResult::Control(Flow::Continue)),
// );
//
// // The field value.
// assert_eq!(
// visit_value::<_, Blocking>(visitor, OwnedStatic(false)).value(),
// VisitResult::Control(Flow::Done)
// );
//
// // The sequence protocol allows for us to wait to decide if there is another item.
// Flow::Continue
// });
//
// // There are no more fields.
// scope.expect_next().once().returning(|_visitor| Flow::Done);
//
// let mut builder = StructBuilder::<Info, DefaultMode, Blocking>::from_seed(()).value();
// let mut visitor = builder.as_visitor();
//
// // We need to provide the map tag to the struct before getting into the sequence.
// // This tag notifies the struct builder to expect the sequence as a map.
// assert_eq!(
// visit_tag::<tags::Map, Blocking, _>(TagConst, visitor.cast(), NoopWalker::new()).value(),
// Ok(VisitResult::Control(Flow::Continue))
// );
//
// // Visit the sequence of fields.
// assert_eq!(
// visit_sequence(visitor, &mut scope).value(),
// VisitResult::Control(Flow::Done)
// );
//
// // The struct is built as the mock walker above makes it.
// assert_eq!(builder.build().value().unwrap(), X { a: false, b: true });
// }
pub mod demo {
use crate::Walk;
use macro_rules_attribute::derive;
use treaty::{effect::{r#async::Async, blocking::{BlockOn, Blocking, Spin}, Effective as _}, transform, Build, DefaultMode};
#[derive(Walk!, Debug)]
pub struct X {
pub a: bool,
pub b: bool,
}
#[derive(Build!, Debug)]
pub struct Y {
pub b: bool,
pub a: bool,
}
#[no_mangle]
pub fn ident(x: X) -> Y {
let other = transform::<<Y as crate::Build<'_, DefaultMode, _>>::Builder, _, Blocking<Spin>>(
((), ()),
Walk::<DefaultMode, _>::into_walker(&x),
);
let other = Spin::block_on(other.into_future());
other.0.unwrap()
}
}