I have a common function that returns a MySQL connection:
pub fn get_db_conn() -> Result<PooledConn> {...}
And all around the application I have code like this:
let mut conn = get_db_conn()?;
let mut tx = conn.start_transaction(TxOpts::default())?;
That kinda breaks the DRY principle and I'd like to simplify that code by only having to call a single function. So I image something like this:
pub fn get_db_conn_and_tx() -> Result<(PooledConn, Transaction)> {
let mut conn = get_db_conn()?;
let mut tx = conn.start_transaction(TxOpts::default())?;
Ok((conn, tx))
}
or this:
pub fn get_db_tx() -> Result<(Transaction)> {
let mut conn = get_db_conn()?;
let mut tx = conn.start_transaction(TxOpts::default())?;
Ok((tx))
}
However, neither of those compiles.
Let's take the first one as an example. This is the error the compiler emits:
error[E0106]: missing lifetime specifier
|
33 | pub fn get_db_conn_with_tx() -> Result<(PooledConn, Transaction)> {
| ^^^^^^^^^^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
33 | pub fn get_db_conn_with_tx() -> Result<(PooledConn, Transaction<'static>)> {
| ~~~~~~~~~~~~~~~~~~~~
I tried changing the result to Result<(PooledConn, Transaction<'static>)>. This time I got:
error[E0515]: cannot return value referencing local variable `conn`
|
35 | let mut tx = conn.start_transaction(TxOpts::default())?;
| ---- `conn` is borrowed here
36 | Ok((conn, tx))
| ^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
Why do I get that error message? I am returning both conn and tx, so shouldn't ownership of both values be transferred to the calling function?
Also, I wonder what would be the best way to implement the second function that returns just a Transaction.