I'm trying to pass an async closure to a function which will start a transaction then call the closure then commit the transaction
impl<'t> Transactional<'t> {
pub async fn run<'result, F>(self, f: F) -> Result<(), anyhow::Error>
where
F: Send + FnOnce(TransactionalCtx<'t>) -> BoxFuture<'t, Result<(), anyhow::Error>> + 't,
{
match self {
Transactional::Postgres(mut conn) => {
let mut txn = conn.transaction().await.map_err(|e| anyhow!(e))?;
f(TransactionalCtx::Postgres(&txn)).await?;
txn.commit().await.map_err(|e| anyhow!(e))?;
}
// Transactional::Oracle(conn) => {
// f(TransactionalCtx::Oracle(&conn)).await?;
// let commit = conn.commit();
// if commit.is_err() {
// conn.rollback();
// commit.map_err(|e| anyhow!(e))?;
// }
// }
Transactional::Oracle(..) => todo!(),
Transactional::Mssql() => todo!(),
}
Ok(())
}
}
#[derive(Clone)]
pub enum TransactionalCtx<'t> {
Postgres(&'t bb8_postgres::tokio_postgres::Transaction<'t>),
Oracle(&'t bb8_oracle::oracle::Connection),
Mssql(),
}
compiler output
error[E0597]: `conn` does not live long enough
--> payments-processor/src/db/mod.rs:197:31
|
190 | impl<'t> Transactional<'t> {
| -- lifetime `'t` defined here
...
197 | let mut txn = conn.transaction().await.map_err(|e| anyhow!(e))?;
| ^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
198 | f(TransactionalCtx::Postgres(&txn)).await?;
| ----------------------------------- argument requires that `conn` is borrowed for `'t`
...
201 | }
| - `conn` dropped here while still borrowed
error[E0597]: `txn` does not live long enough
--> payments-processor/src/db/mod.rs:198:46
|
190 | impl<'t> Transactional<'t> {
| -- lifetime `'t` defined here
...
198 | f(TransactionalCtx::Postgres(&txn)).await?;
| -----------------------------^^^^--
| | |
| | borrowed value does not live long enough
| argument requires that `txn` is borrowed for `'t`
...
201 | }
| - `txn` dropped here while still borrowed
error[E0505]: cannot move out of `txn` because it is borrowed
--> payments-processor/src/db/mod.rs:200:17
|
190 | impl<'t> Transactional<'t> {
| -- lifetime `'t` defined here
...
198 | f(TransactionalCtx::Postgres(&txn)).await?;
| -----------------------------------
| | |
| | borrow of `txn` occurs here
| argument requires that `txn` is borrowed for `'t`
199 |
200 | txn.commit().await.map_err(|e| anyhow!(e))?;
| ^^^ move out of `txn` occurs here