diff --git a/v0.5/Cargo.lock b/v0.5/Cargo.lock index e39fd6b9b..5474d6c3d 100644 --- a/v0.5/Cargo.lock +++ b/v0.5/Cargo.lock @@ -38,6 +38,17 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "backtrace" version = "0.3.74" @@ -184,6 +195,9 @@ dependencies = [ [[package]] name = "fastn-continuation" version = "0.1.0" +dependencies = [ + "async-trait", +] [[package]] name = "fastn-js" diff --git a/v0.5/Cargo.toml b/v0.5/Cargo.toml index 2c9785982..70886707d 100644 --- a/v0.5/Cargo.toml +++ b/v0.5/Cargo.toml @@ -40,6 +40,7 @@ homepage = "https://fastn.com" # using the latest dependency, and what is the plan to move to the latest version. arcstr = "1" +async-trait = "0.1" fastn-builtins = { path = "../fastn-builtins" } fastn-compiler = { path = "fastn-compiler" } fastn-continuation = { path = "fastn-continuation" } diff --git a/v0.5/fastn-continuation/Cargo.toml b/v0.5/fastn-continuation/Cargo.toml index cc1f0f1e6..c2ef53c4b 100644 --- a/v0.5/fastn-continuation/Cargo.toml +++ b/v0.5/fastn-continuation/Cargo.toml @@ -8,4 +8,8 @@ license.workspace = true repository.workspace = true homepage.workspace = true +[features] +async_provider = ["async-trait"] + [dependencies] +async-trait = { workspace = true, optional = true } diff --git a/v0.5/fastn-continuation/src/lib.rs b/v0.5/fastn-continuation/src/lib.rs index 3faf69a22..ef85518e3 100644 --- a/v0.5/fastn-continuation/src/lib.rs +++ b/v0.5/fastn-continuation/src/lib.rs @@ -10,6 +10,25 @@ pub trait Provider { fn provide(&self, input: Self::Input) -> Self::Output; } +#[cfg(feature = "async_provider")] +#[async_trait::async_trait] +pub trait AsyncProvider { + type Input; + type Output; + + async fn provide(&self, input: Self::Input) -> Self::Output; +} + +#[cfg(feature = "async_provider")] +#[async_trait::async_trait] +pub trait AsyncProviderWith { + type Input; + type Output; + type Context; + + async fn provide(&self, context: &mut Self::Context, input: Self::Input) -> Self::Output; +} + pub trait ProviderWith { type Input; type Output; @@ -18,22 +37,6 @@ pub trait ProviderWith { fn provide(&self, context: &mut Self::Context, input: Self::Input) -> Self::Output; } -// impl Provider for dyn Fn(I) -> O { -// type Input = I; -// type Output = O; -// fn provide(&self, input: Self::Input) -> Self::Output { -// self(input) -// } -// } - -// impl Provider for fn(I) -> O { -// type Input = I; -// type Output = O; -// fn provide(&self, input: Self::Input) -> Self::Output { -// self(input) -// } -// } - pub trait Continuation { type Output; type NeededInput; @@ -108,7 +111,24 @@ impl Result { } } - pub async fn consume_async(mut self, f: impl Fn(C::NeededInput) -> Fut) -> C::Output + #[cfg(feature = "async_provider")] + pub async fn consume_async

(mut self, p: P) -> C::Output + where + P: AsyncProvider, + { + loop { + match self { + Result::Stuck(ic, input) => { + self = ic.continue_after(p.provide(input).await); + } + Result::Done(c) => { + return c; + } + } + } + } + + pub async fn consume_async_fn(mut self, f: impl Fn(C::NeededInput) -> Fut) -> C::Output where Fut: std::future::Future, { @@ -124,7 +144,25 @@ impl Result { } } - pub async fn consume_with_async( + #[cfg(feature = "async_provider")] + pub async fn consume_with_async

(mut self, p: P) -> C::Output + where + P: AsyncProviderWith, + { + loop { + match self { + Result::Stuck(mut ic, input) => { + let o = p.provide(&mut ic, input).await; + self = ic.continue_after(o); + } + Result::Done(c) => { + return c; + } + } + } + } + + pub async fn consume_with_async_fn( mut self, f: impl Fn(&mut C, C::NeededInput) -> Fut, ) -> C::Output diff --git a/v0.5/fastn/src/main.rs b/v0.5/fastn/src/main.rs index 1c4988536..73efeafa7 100644 --- a/v0.5/fastn/src/main.rs +++ b/v0.5/fastn/src/main.rs @@ -3,7 +3,7 @@ async fn main() { let command = fastn::commands::parse(); let mut package = fastn_package::Package::reader().consume_fn(fastn::full_filler); let router = fastn_router::Router::reader() - .consume_async(fastn::full_filler_async) + .consume_async_fn(fastn::full_filler_async) .await; // read config here and pass to everyone? // do common build stuff here