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