Diffstat (limited to 'src/effect.rs')
-rw-r--r--src/effect.rs245
1 files changed, 209 insertions, 36 deletions
diff --git a/src/effect.rs b/src/effect.rs
index 3e3b8da..b0203bc 100644
--- a/src/effect.rs
+++ b/src/effect.rs
@@ -1,65 +1,237 @@
use core::{
+ future::Future,
marker::PhantomData,
- pin::pin,
+ pin::{pin, Pin},
ptr,
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
};
+use futures::FutureExt;
+use pin_project::pin_project;
+
use crate::{higher_ranked_trait, higher_ranked_type, hkt::Marker};
-higher_ranked_trait! {
- pub type class SendFuture[Output] for<'a> {
- type Bound = &'a Output;
+// higher_ranked_trait! {
+// pub type class Effective['lt, E] for<'a> {
+// type Bound = &'a (&'lt (), T, E);
+//
+// type T: { Adapters<'a, Effect = E, T = T> + Sized + 'a }
+// where {
+// 'lt: 'a,
+// T: 'a,
+// E: Effect,
+// };
+//
+// type HigherRanked: {} where {
+// E: Effect,
+// };
+// }
+// }
- type T: { core::future::Future<Output = Output> + Sized + Send + 'a }
- where {
- Output: 'a
- };
- type HigherRanked: {} where {
- // Output: Send
- };
- }
+// fn do_thing<E: Effect>() -> ObjSafe<'static, i32, E> {
+// E::ready(42).with(|x| {
+// other::<E>(x).map(|x| x + 1).into()
+// }).into()
+// }
+//
+// fn other<E: Effect>(x: &i32) -> ObjSafe<'_, &i32, E> {
+// E::ready(x).into()
+// }
+
+// pub mod Effective {
+//
+// }
+//
+pub trait Adapters<'lt>: Into<<Self::Effect as Effect>::ObjSafe<'lt, Self::T>> + 'lt {
+ type Effect: Effect;
+ type T: 'lt;
+
+ type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T>: Adapters<'a, Effect = Self::Effect, T = T>
+ where
+ 'lt: 'a;
+
+ fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
+ where
+ F: FnOnce(Self::T) -> R,
+ 'lt: 'a;
}
/// Trait for effects.
-pub trait Effect: Send + Sync + 'static {
- type Future<T: Send>: SendFuture::MemberType<T>;
+pub trait Effect: Sized + Send + Sync + 'static {
+ type ObjSafe<'a, T: 'a>: Adapters<'a, Effect = Self, T = T>;
- fn wrap<'a, F>(future: F) -> SendFuture::T<'a, F::Output, Self::Future<F::Output>>
+ type Ready<'a, T: 'a>: Adapters<'a, Effect = Self, T = T>;
+
+ fn ready<'a, T: 'a>(x: T) -> Self::Ready<'a, T>;
+
+ type With<'a, T: 'a, R: 'a, F: 'a + FnOnce(&mut T) -> R>: Adapters<'a, Effect = Self, T = R>;
+
+ fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> Self::With<'a, T, R::T, F>
+ where
+ R: Adapters<'a, Effect = Self>,
+ F: FnOnce(&mut T) -> R;
+}
+
+pub type ObjSafe<'a, T, E> = <E as Effect>::ObjSafe<'a, T>;
+
+pub enum Blocking {}
+
+impl Effect for Blocking {
+ type ObjSafe<'a, T: 'a> = Value<T>;
+
+ type Ready<'a, T: 'a> = Value<T>;
+
+ fn ready<'a, T: 'a>(x: T) -> Self::Ready<'a, T> {
+ Value(x)
+ }
+
+ type With<'a, T: 'a, R: 'a, F: 'a + FnOnce(&mut T) -> R> = Value<R>;
+
+ fn with<'a, T: 'a, R: 'a, F: 'a>(x: T, f: F) -> Self::With<'a, T, R::T, F>
+ where
+ R: Adapters<'a, Effect = Self>,
+ F: FnOnce(&mut T) -> R {
+ let mut ctx = x;
+ Value(f(&mut ctx))
+ }
+}
+
+pub struct Value<T>(pub T);
+
+impl<'b, U: 'b> Adapters<'b> for Value<U> {
+ type Effect = Blocking;
+
+ type T = U;
+
+ type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T> = Value<T> where 'b: 'a;
+
+ fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
where
- F: core::future::Future + Send + 'a,
- <F as core::future::Future>::Output: Send;
+ F: FnOnce(Self::T) -> R,
+ 'b: 'a,
+ {
+ Value(f(self.0))
+ }
+}
- fn ready<'a, T: Send>(value: T) -> SendFuture::T<'a, T, Self::Future<T>>;
+/*
+pub enum Async {}
- fn map<'a, T, U, F>(
- future: SendFuture::T<'a, T, Self::Future<T>>,
- func: F,
- ) -> SendFuture::T<'a, U, Self::Future<U>>
+impl Effect for Async {
+ type ObjSafe<'a, T: 'a> = BoxedFuture<'a, T>;
+
+ type Ready<'a, T: 'a> = AsyncValue<T>;
+
+ fn ready<'a, T: 'a>(x: T) -> Self::Ready<'a, T> {
+ AsyncValue(x)
+ }
+}
+
+pub struct AsyncValue<T>(pub T);
+
+pub struct BoxedFuture<'a, T: 'a>(pub Pin<Box<dyn Future<Output = T> + 'a>>);
+
+impl<'b, U: 'b> Adapters<'b> for AsyncValue<U> {
+ type Effect = Async;
+
+ type T = U;
+
+ type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T> = AsyncValue<T> where 'b: 'a;
+
+ fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
where
- T: Send,
- U: Send,
- F: FnOnce(T) -> U + Send + 'a;
+ F: FnOnce(Self::T) -> R,
+ 'b: 'a,
+ {
+ AsyncValue(f(self.0))
+ }
+}
- #[cfg(feature = "alloc")]
- #[inline]
- fn wrap_boxed<'a, F>(
- future: core::pin::Pin<Box<F>>,
- ) -> SendFuture::T<'a, F::Output, Self::Future<F::Output>>
+impl<'b, U: 'b> Adapters<'b> for BoxedFuture<'b, U> {
+ type Effect = Async;
+
+ type T = U;
+
+ type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T> = AsyncMap<Self, F> where 'b: 'a;
+
+ fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
where
- F: core::future::Future + Send + 'a,
- <F as core::future::Future>::Output: Send,
+ F: FnOnce(Self::T) -> R,
+ 'b: 'a,
+ {
+ AsyncMap {
+ map: futures::FutureExt::map(self, f)
+ }
+ }
+}
+
+#[pin_project]
+pub struct AsyncMap<Fut, F> {
+ #[pin]
+ map: futures::future::Map<Fut, F>,
+}
+
+impl<'b, U: 'b, Fut0: 'b, F0: 'b> Adapters<'b> for AsyncMap<Fut0, F0>
+where
+ Fut0: Future,
+ F0: FnOnce(Fut0::Output) -> U,
+{
+ type Effect = Async;
+
+ type T = U;
+
+ type Map<'a, T: 'a, F: 'a + FnOnce(Self::T) -> T> = AsyncMap<Self, F> where 'b: 'a;
+
+ fn map<'a, R: 'a, F: 'a>(self, f: F) -> Self::Map<'a, R, F>
+ where
+ F: FnOnce(Self::T) -> R,
+ 'b: 'a,
{
- Self::wrap(future)
+ AsyncMap {
+ map: futures::FutureExt::map(self, f)
+ }
+ }
+}
+
+impl<T, Fut, F> Future for AsyncMap<Fut, F>
+where
+ Fut: Future,
+ F: FnOnce(Fut::Output) -> T,
+{
+ type Output = T;
+
+ fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ let this = self.project();
+ this.map.poll(cx)
+ }
+}
+
+impl<'a, T> Future for BoxedFuture<'a, T> {
+ type Output = T;
+
+ fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+ self.0.poll_unpin(cx)
}
}
-pub type Future<'a, T, E> = SendFuture::T<'a, T, <E as Effect>::Future<T>>;
+impl<'a, T, Fut: 'a, F: 'a> From<AsyncMap<Fut, F>> for BoxedFuture<'a, T>
+where
+ Fut: Future,
+ F: FnOnce(Fut::Output) -> T,
+{
+ fn from(value: AsyncMap<Fut, F>) -> Self {
+ BoxedFuture(Box::pin(value.map))
+ }
+}
-pub struct Blocking<B = Spin> {
- _marker: PhantomData<fn() -> B>,
+impl<'a, T: 'a> From<AsyncValue<T>> for BoxedFuture<'a, T> {
+ fn from(value: AsyncValue<T>) -> Self {
+ BoxedFuture(Box::pin(futures::future::ready(value.0)))
+ }
}
+*/
+/*
pub trait ReadyValue: core::future::Future {
fn value(self) -> Self::Output;
}
@@ -272,3 +444,4 @@ impl Effect for Async {
sealed::BoxedFuture::Box(future)
}
}
+*/