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