Diffstat (limited to 'src/protocol.rs')
| -rw-r--r-- | src/protocol.rs | 132 |
1 files changed, 116 insertions, 16 deletions
diff --git a/src/protocol.rs b/src/protocol.rs index c763730..fccb8ed 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -38,43 +38,143 @@ use core::{ pin::{pin, Pin}, ptr, task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + marker::PhantomData, }; use crate::any::AnyTrait; -pub mod visitor; -pub mod walker; +// pub mod visitor; +// pub mod walker; #[cfg(all(feature = "alloc", not(feature = "std")))] use alloc::boxed::Box; -pub type Visitor<'a, 'ctx> = dyn AnyTrait<'ctx> + 'a; -pub type Walker<'a, 'ctx> = dyn AnyTrait<'ctx> + 'a; +pub type Visitor<'a, 'ctx, Effect> = <<Effect as self::Effect<'ctx>>::VisitorHkt as ForLtAnyTraitSendObj<'a, 'ctx, Bound<'a, 'ctx>>>::T; +pub type Walker<'a, 'ctx, Effect> = <<Effect as self::Effect<'ctx>>::WalkerHkt as ForLtAnyTraitSendObj<'a, 'ctx, Bound<'a, 'ctx>>>::T; -pub trait Effect: 'static { - type ControlFlow<'a, C, B>; +pub trait AnyTraitObj<'a, 'ctx: 'a>: AnyTraitSendObj<'a, 'ctx> { + fn from_obj(value: &'a mut (dyn AnyTrait<'ctx> + 'a)) -> Self; } -pub type ControlFlowFor<'a, E = SyncEffect, C = (), B = ()> = <E as Effect>::ControlFlow<'a, C, B>; +// Lifetime bound to be used in `for<'lt>` blocks. +pub type Bound<'lt, 'bound> = &'lt &'bound (); + +pub trait ForLtAnyTraitSendObj<'lt, 'ctx: 'lt, B> { + type T: AnyTraitSendObj<'lt, 'ctx>; +} + +pub trait HktAnyTraitSendObj<'ctx>: for<'lt> ForLtAnyTraitSendObj<'lt, 'ctx, Bound<'lt, 'ctx>> {} +impl<'ctx, T> HktAnyTraitSendObj<'ctx> for T where T: for<'lt> ForLtAnyTraitSendObj<'lt, 'ctx, Bound<'lt, 'ctx>> {} + +pub trait ForLt<'lt, 'ctx: 'lt, B> { + type T; +} + +pub trait Hkt<'ctx>: for<'lt> ForLt<'lt, 'ctx, Bound<'lt, 'ctx>> {} +impl<'ctx, T> Hkt<'ctx> for T where T: for<'lt> ForLt<'lt, 'ctx, Bound<'lt, 'ctx>> {} + +pub trait AnyTraitSendObj<'a, 'ctx: 'a> { + fn from_obj_send(value: &'a mut (dyn AnyTrait<'ctx> + Send + 'a)) -> Self; + fn as_obj(&self) -> &dyn AnyTrait<'ctx>; + fn as_obj_mut(&mut self) -> &mut dyn AnyTrait<'ctx>; + fn into_obj(self) -> &'a mut dyn AnyTrait<'ctx>; +} + +impl<'a, 'ctx: 'a> AnyTraitSendObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + 'a) { + fn from_obj_send(value: &'a mut (dyn AnyTrait<'ctx> + Send + 'a)) -> Self { + value + } + + fn as_obj(&self) -> &dyn AnyTrait<'ctx> { + *self + } + + fn as_obj_mut(&mut self) -> &mut dyn AnyTrait<'ctx> { + *self + } + + fn into_obj(self) -> &'a mut dyn AnyTrait<'ctx> { + self + } +} + +impl<'a, 'ctx: 'a> AnyTraitSendObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + Send + 'a) { + fn from_obj_send(value: &'a mut (dyn AnyTrait<'ctx> + Send + 'a)) -> Self { + value + } + + fn as_obj(&self) -> &dyn AnyTrait<'ctx> { + *self + } + + fn as_obj_mut(&mut self) -> &mut dyn AnyTrait<'ctx> { + *self + } + + fn into_obj(self) -> &'a mut dyn AnyTrait<'ctx> { + self + } +} + +impl<'a, 'ctx: 'a> AnyTraitObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + 'a) { + fn from_obj(value: &'a mut (dyn AnyTrait<'ctx> + 'a)) -> Self { + value + } +} + +pub trait Effect<'ctx, C = (), B = ()>: 'static { + type VisitorHkt: HktAnyTraitSendObj<'ctx>; + type WalkerHkt: HktAnyTraitSendObj<'ctx>; + type ControlFlowHkt: Hkt<'ctx>; +} + +pub type ControlFlowFor<'a, 'ctx, E = SyncEffect, C = (), B = ()> = + <<E as Effect<'ctx, C, B>>::ControlFlowHkt as ForLt<'a, 'ctx, Bound<'a, 'ctx>>>::T; pub enum SyncEffect {} -impl Effect for SyncEffect { - type ControlFlow<'a, C, B> = core::ops::ControlFlow<B, C>; +pub struct AnyTraitSendObjHkt<'ctx>(PhantomData<fn() -> &'ctx ()>); + +impl<'a, 'ctx> ForLtAnyTraitSendObj<'a, 'ctx, Bound<'a, 'ctx>> for AnyTraitSendObjHkt<'ctx> { + type T = &'a mut (dyn AnyTrait<'ctx> + Send + 'a); +} + +pub struct AnyTraitObjHkt<'ctx>(PhantomData<fn() -> &'ctx ()>); + +impl<'a, 'ctx> ForLtAnyTraitSendObj<'a, 'ctx, Bound<'a, 'ctx>> for AnyTraitObjHkt<'ctx> { + type T = &'a mut (dyn AnyTrait<'ctx> + 'a); } -fn noop() -> Waker { - const VTABLE: RawWakerVTable = RawWakerVTable::new(|_| RAW, |_| {}, |_| {}, |_| {}); - const RAW: RawWaker = RawWaker::new(ptr::null(), &VTABLE); +pub struct SyncControlFlowHkt<'ctx, C, B>(PhantomData<fn() -> (&'ctx (), C, B)>); - unsafe { Waker::from_raw(RAW) } +impl<'a, 'ctx, C, B> ForLt<'a, 'ctx, Bound<'a, 'ctx>> for SyncControlFlowHkt<'ctx, C, B> { + type T = core::ops::ControlFlow<B, C>; +} + +impl<'ctx, C, B> Effect<'ctx, C, B> for SyncEffect { + type ControlFlowHkt = SyncControlFlowHkt<'ctx, C, B>; + + type VisitorHkt = AnyTraitSendObjHkt<'ctx>; + + type WalkerHkt = AnyTraitSendObjHkt<'ctx>; +} + +#[cfg(feature = "alloc")] +pub struct AsyncControlFlowHkt<'ctx, C, B>(PhantomData<fn() -> (&'ctx (), C, B)>); + +#[cfg(feature = "alloc")] +impl<'a, 'ctx, C, B> ForLt<'a, 'ctx, Bound<'a, 'ctx>> for AsyncControlFlowHkt<'ctx, C, B> { + type T = core::pin::Pin< + Box<dyn core::future::Future<Output = core::ops::ControlFlow<B, C>> + Send + 'a>, + >; } #[cfg(feature = "alloc")] pub enum AsyncEffect {} #[cfg(feature = "alloc")] -impl Effect for AsyncEffect { - type ControlFlow<'a, C, B> = - core::pin::Pin<Box<dyn core::future::Future<Output = core::ops::ControlFlow<B, C>> + 'a>>; +impl<'ctx, C, B> Effect<'ctx, C, B> for AsyncEffect { + type VisitorHkt = AnyTraitObjHkt<'ctx>; + type WalkerHkt = AnyTraitObjHkt<'ctx>; + type ControlFlowHkt = AsyncControlFlowHkt<'ctx, C, B>; } |