use std::{future::Future, marker::PhantomData, pin::Pin, thread::yield_now, time::Duration};
use treaty::{
any::{any_trait, static_wrapper::OwnedStatic, AnyTrait, IndirectLtAny, LtTypeId},
build_with, into_walker,
protocol::{
visitor::Value, AnyTraitSendObj, AsyncEffect, ControlFlowFor, Effect, SyncEffect, Visitor,
},
Build, Builder, Walker,
};
#[test]
fn demo() {
let hook = Hook {
inner: into_walker(true),
_marker: PhantomData,
};
let x = build_with::<<bool as Build<_>>::Builder, _>(hook).unwrap();
dbg!(x);
todo!();
}
struct Hook<T, Effect> {
inner: T,
_marker: PhantomData<fn() -> Effect>,
}
struct VisitorHook<'a, 'ctx: 'a, E: Effect> {
inner: E::Visitor<'a, 'ctx>,
}
impl<'ctx, T: Walker<'ctx, Effect = AsyncEffect> + Send> Walker<'ctx> for Hook<T, AsyncEffect>
where
<T as Walker<'ctx>>::Error: Send,
<T as Walker<'ctx>>::Output: Send,
{
type Effect = T::Effect;
type Error = T::Error;
type Output = T::Output;
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx, T::Effect>,
) -> ControlFlowFor<'a, Self::Effect, Self::Output, Self::Error>
where
Self: 'a,
{
let visitor: &'a mut (dyn AnyTrait<'ctx> + Send + 'a) = is_send(visitor);
let inner: T = is_send(self.inner);
let x = async move {
let mut visitor = is_send(VisitorHook::<Self::Effect> {
inner: is_send(visitor),
});
let flow: Pin<
Box<dyn Future<Output = core::ops::ControlFlow<Self::Error, Self::Output>> + Send>,
> = is_send(is_send(inner).walk(is_send(&mut visitor)));
is_send(assert_send(is_send(flow)).await)
};
let y: Pin<
Box<dyn Future<Output = core::ops::ControlFlow<Self::Error, Self::Output>> + Send>,
> = Box::pin(assert_send(x));
todo!();
}
}
pub trait Captures<U> {}
impl<T: ?Sized, U> Captures<U> for T {}
pub fn make_async<'a, 'ctx, T: Walker<'ctx, Effect = AsyncEffect> + Send + 'a>(
visitor: &'a mut (dyn AnyTrait<'ctx> + Send + 'a),
inner: T,
) -> impl futures::Future<Output = ()> + Send + Captures<&'ctx ()> + 'a
where
AsyncEffect: Send,
T::Error: Send,
T::Output: Send,
T::Effect: Send,
{
async move {
let mut visitor = is_send(VisitorHook::<AsyncEffect> {
inner: is_send(visitor),
});
// let flow: Pin<Box<dyn Future<Output = _> + Send>> =
if false {
let _: Pin<Box<dyn Future<Output = _> + Send>> =
is_send(is_send(inner).walk(is_send(todo!())));
}
tokio::time::sleep(Duration::from_secs(1)).await;
// is_send(assert_send(is_send(flow)).await);
()
}
}
pub fn is_send<T: Send>(x: T) -> T {
x
}
pub fn assert_send<T>(
s: impl futures::Future<Output = T> + Send,
) -> impl futures::Future<Output = T> + Send {
s
}
impl<'ctx, T: Walker<'ctx, Effect = SyncEffect>> Walker<'ctx> for Hook<T, SyncEffect> {
type Effect = T::Effect;
type Error = T::Error;
type Output = T::Output;
fn walk<'a>(
self,
visitor: Visitor<'a, 'ctx, T::Effect>,
) -> ControlFlowFor<'a, Self::Effect, Self::Output, Self::Error>
where
Self: 'a,
{
let mut visitor = VisitorHook::<Self::Effect> { inner: visitor };
let flow = self.inner.walk(&mut visitor);
flow
}
}
impl<'b, 'ctx, E: Effect> AnyTrait<'ctx> for VisitorHook<'b, 'ctx, E> {
fn upcast_to_id<'a>(
&'a self,
id: treaty::any::LtTypeId<'ctx>,
) -> Option<treaty::any::IndirectLtAny<'a, 'ctx, treaty::any::Ref>>
where
'ctx: 'a,
{
match id {
id => self.inner.as_obj().upcast_to_id(id),
}
}
fn upcast_to_id_mut<'a>(
&'a mut self,
id: treaty::any::LtTypeId<'ctx>,
) -> Option<treaty::any::IndirectLtAny<'a, 'ctx, treaty::any::Mut>>
where
'ctx: 'a,
{
match id {
id if id == LtTypeId::of::<dyn Value<'a, OwnedStatic<bool>> + 'a>() => {
if self.inner.as_obj_mut().upcast_to_id_mut(id).is_some() {
Some(IndirectLtAny::<'a, 'ctx, _>::new::<
dyn Value<'a, OwnedStatic<bool>> + 'a,
>(self as _))
} else {
None
}
}
id => self.inner.as_obj_mut().upcast_to_id_mut(id),
}
}
}
impl<'a, 'b, 'ctx, E: Effect> Value<'a, OwnedStatic<bool>> for VisitorHook<'b, 'ctx, E> {
#[inline]
fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a> {
let visitor = self
.inner
.as_obj_mut()
.upcast_mut::<dyn Value<'a, OwnedStatic<bool>> + 'a>()
.unwrap();
println!("Hooked bool: {}", value);
visitor.visit(OwnedStatic(!value))
}
}