Expand description
A handle trait for asynchronous context pipeline.
Maintain context in multiple handlers.
Examples
use handle::{Handle, BoxFuture};
use futures::executor::block_on;
use std::{future::Future, sync::Arc};
type Result = anyhow::Result<()>;
struct Context {
index: usize,
middleware: Vec<Box<dyn for<'a> Handle<'a, Context, Output = Result>>>,
}
impl Context {
async fn next(&mut self) -> Result {
if let Some(m) = self.middleware.pop() {
m.call(self).await
} else {
Ok(())
}
}
}
async fn a(cx: &mut Context) -> Result {
let size = cx.middleware.len();
let repeat = "-".repeat(2 * size);
println!("exec Fn a --{}>> {:>2}", repeat, cx.index);
cx.index += 1;
let fut = cx.next().await;
cx.index += 1;
println!("exec Fn a --{}<< {:>2}", repeat, cx.index);
fut
}
#[derive(Clone)]
struct A {
index: usize,
}
impl<'a> Handle<'a, Context> for A {
type Output = Result;
fn call(&'a self, cx: &'a mut Context) -> BoxFuture<'a, Self::Output> {
Box::pin(async move {
let size = cx.middleware.len();
let repeat = "-".repeat(2 * size);
println!("exec St A --{}>> {:>2}", repeat, cx.index);
cx.index += self.index;
let fut = cx.next().await;
cx.index -= self.index;
println!("exec St A --{}<< {:>2}", repeat, cx.index);
fut
})
}
}
#[async_std::main]
async fn main() -> Result {
let mut cx = Context {
index: 0,
middleware: vec![Box::new(a), Box::new(A { index: 2 })],
};
let result = cx.next().await;
assert!(result.is_ok());
assert_eq!(result.unwrap(), ());
Ok(())
}
Traits§
- Handle
- A handle trait for asynchronous context pipeline.
Type Aliases§
- BoxFuture
- An owned dynamically typed [
Future
] for use in cases where you can’t statically type your result or need to add some indirection.