Diffstat (limited to 'src/protocol.rs')
-rw-r--r--src/protocol.rs87
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>;
}