scoped-futures

A utility crate for imposing upper bounds on Future lifetimes. This is especially useful for callbacks that use higher-ranked lifetimes in their return type, where it can prevent 'static bounds from being placed on a returned Future.

Example

```rust use core::pin::Pin; use scoped_futures::{ScopedBoxFuture, ScopedFutureExt};

pub struct Db { count: u8, }

impl Db { async fn transaction<'a, F, T, E>(&mut self, callback: F) -> Result where // ScopedBoxFuture imposes a lifetime bound on 'b which prevents the hrtb below needing // to be satisfied for all lifetimes (including 'static) and instead only lifetimes // which live at most as long as 'a F: for<'b /* where 'a: 'b */> FnOnce(&'b mut Self) -> ScopedBoxFuture<'a, 'b, Result> + Send + 'a, T: 'a, E: 'a, { callback(self).await } }`

pub async fn testtransaction<'a, 'b>( db: &mut Db, ok: &'a str, err: &'b str, isok: bool, ) -> Result<&'a str, &'b str> { // note the lack of move or any cloning in front of the closure db.transaction(|db| async move { db.count += 1; if isok { Ok(ok) } else { Err(err) } }.scopeboxed()).await?;

// note that `async` can be used instead of `async move` since the callback param is unused
db.transaction(|_| async {
    if is_ok {
        Ok(ok)
    } else {
        Err(err)
    }
}.scope_boxed()).await

}

[test]

fn testtransactionworks() { futures::executor::blockon(async { let mut db = Db { count: 0 }; let ok = String::from("ok"); let err = String::from("err"); let result = testtransaction(&mut db, &ok, &err, true).await; asserteq!(ok, result.unwrap()); asserteq!(1, db.count); }) } ```