Diffstat (limited to 'src/effect.rs')
| -rw-r--r-- | src/effect.rs | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/src/effect.rs b/src/effect.rs new file mode 100644 index 0000000..dd8b971 --- /dev/null +++ b/src/effect.rs @@ -0,0 +1,110 @@ +use crate::{any::AnyTrait, hkt, type_class}; + +pub trait AsObj<'a, 'ctx: 'a> { + 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> AsObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + 'a) { + 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> AsObj<'a, 'ctx> for &'a mut (dyn AnyTrait<'ctx> + Send + 'a) { + 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 + } +} + +type_class!(for<'lt, 'ctx> pub as_obj: AsObj<'lt, 'ctx>); +type_class!(for<'lt, 'ctx> pub any_t); + +pub trait EffectAnyTrait<'ctx>: 'static { + /// The `dyn AnyTrait<'ctx>` for the effect. + /// + /// this allows adding extra bounds to the trait object. + type AnyTrait: as_obj::Hkt<'ctx>; +} + +/// Trait for effects. +pub trait Effect<'ctx, T>: EffectAnyTrait<'ctx> { + /// The type functions return for this effect. + /// + /// This type should resolve into a `T`. + type Yield: any_t::Hkt<'ctx>; +} + +pub type Yield<'a, 'ctx, T, E> = any_t::T<'a, 'ctx, <E as Effect<'ctx, T>>::Yield>; + +pub enum SyncEffect {} + +hkt!((as_obj): for<'a, 'ctx> pub AnyTraitSendObj => &'a mut (dyn AnyTrait<'ctx> + Send + 'a)); +hkt!((as_obj): for<'a, 'ctx> pub AnyTraitObj => &'a mut (dyn AnyTrait<'ctx> + 'a)); + +hkt!((any_t): for<'a, 'ctx> pub SyncYield[T] => T); + +impl<'ctx, T> Effect<'ctx, T> for SyncEffect { + type Yield = SyncYield<'ctx, T>; +} + +impl<'ctx> EffectAnyTrait<'ctx> for SyncEffect { + type AnyTrait = AnyTraitObj<'ctx>; +} + +#[cfg(feature = "alloc")] +hkt!((any_t): for<'a, 'ctx> pub AsyncSendYield[T] => + core::pin::Pin< + Box<dyn core::future::Future<Output = T> + Send + 'a>, + > +); + +#[cfg(feature = "alloc")] +pub enum AsyncSendEffect {} + +#[cfg(feature = "alloc")] +impl<'ctx, T> Effect<'ctx, T> for AsyncSendEffect { + type Yield = AsyncSendYield<'ctx, T>; +} + +#[cfg(feature = "alloc")] +impl<'ctx> EffectAnyTrait<'ctx> for AsyncSendEffect { + type AnyTrait = AnyTraitSendObj<'ctx>; +} + +#[cfg(feature = "alloc")] +hkt!((any_t): for<'a, 'ctx> pub AsyncYield[T] => + core::pin::Pin< + Box<dyn core::future::Future<Output = T> + 'a>, + > +); + +#[cfg(feature = "alloc")] +pub enum AsyncEffect {} + +#[cfg(feature = "alloc")] +impl<'ctx, T> Effect<'ctx, T> for AsyncEffect { + type Yield = AsyncYield<'ctx, T>; +} + +#[cfg(feature = "alloc")] +impl<'ctx> EffectAnyTrait<'ctx> for AsyncEffect { + type AnyTrait = AnyTraitObj<'ctx>; +} |