Diffstat (limited to 'src/protocol.rs')
| -rw-r--r-- | src/protocol.rs | 87 |
1 files changed, 23 insertions, 64 deletions
diff --git a/src/protocol.rs b/src/protocol.rs index c4a7f7a..7ff6988 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -42,37 +42,21 @@ use core::{ }; use crate::any::AnyTrait; +use crate::hkt::{type_class, hkt}; -// 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, 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 type Visitor<'a, 'ctx, Effect> = any_trait_send_obj::T<'a, 'ctx, <Effect as self::Effect<'ctx>>::VisitorHkt>; +pub type Walker<'a, 'ctx, Effect> = any_trait_send_obj::T<'a, 'ctx, <Effect as self::Effect<'ctx>>::WalkerHkt>; pub trait AnyTraitObj<'a, 'ctx: 'a>: AnyTraitSendObj<'a, 'ctx> { fn from_obj(value: &'a mut (dyn AnyTrait<'ctx> + 'a)) -> Self; } -// 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>; @@ -122,71 +106,46 @@ impl<'a, 'ctx: 'a> AnyTraitObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + 'a) { } } +type_class!(for<'lt, 'ctx> pub any_trait_send_obj: AnyTraitSendObj<'lt, 'ctx>); +type_class!(for<'lt, 'ctx> pub any_t); + pub trait Effect<'ctx, C = (), B = ()>: 'static { - type VisitorHkt: HktAnyTraitSendObj<'ctx>; - type WalkerHkt: HktAnyTraitSendObj<'ctx>; - type ControlFlowHkt: Hkt<'ctx>; + type VisitorHkt: any_trait_send_obj::Hkt<'ctx>; + type WalkerHkt: any_trait_send_obj::Hkt<'ctx>; + type ControlFlowHkt: any_t::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; + any_t::T<'a, 'ctx, <E as Effect<'ctx, C, B>>::ControlFlowHkt>; pub enum SyncEffect {} -pub struct AnyTraitSendObjHkt<'ctx>(PhantomData<fn() -> &'ctx ()>); +hkt!((any_trait_send_obj): for<'a, 'ctx> pub AnyTraitSendObjHkt => &'a mut (dyn AnyTrait<'ctx> + Send + 'a)); +hkt!((any_trait_send_obj): for<'a, 'ctx> pub AnyTraitObjHkt => &'a mut (dyn AnyTrait<'ctx> + 'a)); -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); -} - -pub struct SyncControlFlowHkt<'ctx, C, B>(PhantomData<fn() -> (&'ctx (), C, B)>); - -impl<'a, 'ctx, C, B> ForLt<'a, 'ctx, Bound<'a, 'ctx>> for SyncControlFlowHkt<'ctx, C, B> { - type T = core::ops::ControlFlow<B, C>; -} +hkt!((any_t): for<'a, 'ctx> pub SyncControlFlowHkt[C, B] => 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>; -} - -macro_rules! hkt { - (for<$lt:lifetime bound by $bound:lifetime> $name:ident$([$($generic:tt)*])? = $($type:tt)*) => { - pub struct $name<$bound $(, $($generic)*)?>(core::marker::PhantomData<fn() -> (&$bound () $(, $($generic)*)?)>); + type VisitorHkt = AnyTraitObjHkt<'ctx>; - impl<$lt, $bound $(, $($generic)*)?> crate::protocol::ForLt<$lt, $bound, Bound<$lt, $bound>> for $name<$bound $(, $($generic)*)?> { - type T = $($type)*; - } - } + type WalkerHkt = AnyTraitObjHkt<'ctx>; } -hkt!(for<'a bound by 'ctx> Demo = &'a &'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< +hkt!((any_t): for<'a, 'ctx> pub AsyncControlFlowHkt[C, B] => + 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<'ctx, C, B> Effect<'ctx, C, B> for AsyncEffect { - type VisitorHkt = AnyTraitObjHkt<'ctx>; - type WalkerHkt = AnyTraitObjHkt<'ctx>; + type VisitorHkt = AnyTraitSendObjHkt<'ctx>; + type WalkerHkt = AnyTraitSendObjHkt<'ctx>; type ControlFlowHkt = AsyncControlFlowHkt<'ctx, C, B>; } |