Skip to content

Instantly share code, notes, and snippets.

@sibu-github
Created March 12, 2023 17:34
Show Gist options
  • Save sibu-github/af5145595bcf4554475abc1cc55a06d0 to your computer and use it in GitHub Desktop.
Save sibu-github/af5145595bcf4554475abc1cc55a06d0 to your computer and use it in GitHub Desktop.
async closure with the closure taking references in the argument
use futures::future::{BoxFuture, FutureExt};
#[tokio::main]
async fn main() {
println!("Hello, world!");
let db = AppDatabase(0);
let r = db.execute_transaction(transaction).await;
println!("{:?}", r);
}
fn transaction<'a>(
db: &'a AppDatabase,
session: &'a mut DatabaseSession,
) -> BoxFuture<'a, anyhow::Result<()>> {
let val = 5;
async move { db.insert_with_session(val, session).await }.boxed()
}
struct AppDatabase(i32);
struct DatabaseSession(i32);
impl AppDatabase {
async fn execute_transaction<F>(&self, f: F) -> anyhow::Result<()>
where
F: for<'a> Fn(
&'a AppDatabase,
&'a mut DatabaseSession,
) -> BoxFuture<'a, anyhow::Result<()>>,
{
let mut session = DatabaseSession(0);
let result = f(&self, &mut session).await;
if result.is_err() {
println!("rollback transaction here");
result
} else {
println!("commit transaction here");
Ok(())
}
}
async fn insert_with_session(
&self,
val: i32,
session: &mut DatabaseSession,
) -> anyhow::Result<()> {
println!("some dummy insert operation here");
session.0 = val;
Ok(())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment