How to modify this code to make it compile?
I'm trying to write a certain grpc service, which in one method uses a stream to send a large amount of data. The data transmitted via the stream have several different types, and at the proto level, they are defined as oneof, while at the rust level, it is visible as a certain enum with additional values for its elements. With the appearance of a certain type of information, I want to initiate a transaction, and then, when the data to be written to the database comes through the stream, save it with a dedicated method (for the test duration it could be located in StreamingContext, because I would like to hide the entire database handling in a struct). When an end-of-transaction marker appears in the stream, then I would like to call Commit or Rollback depending on the situation.
Unfortunately, what seemed like a simple matter to define, such as saving a Client object for postgres and the transaction that this client began in a struct, has become complicated.
I assumed that the ownership model in this case was very simple, but I was mistaken. The aim of this code is to place the Client for postgres and the transaction in the fields of the StreamingContext struct.
How can this be achieved?
mod probl_desc {
use anyhow::Result;
use tokio_postgres_rustls::MakeRustlsConnect;
use bb8::PooledConnection;
use bb8_postgres::PostgresConnectionManager;
pub type PooledPostgresConnection<'a> = PooledConnection<'a, PostgresConnectionManager<MakeRustlsConnect>>;
pub struct StreamingContext<'a, 'b> {
pub conn: PooledPostgresConnection<'a>,
pub transaction: Option<tokio_postgres::Transaction<'b>>,
}
impl<'a, 'b> StreamingContext<'a, 'b> {
pub fn new(conn: PooledPostgresConnection<'a>) -> StreamingContext<'a, 'b> {
StreamingContext {conn, transaction: None}
}
pub async fn start_transaction(&'a mut self) -> Result<()> {
let transaction = self.conn.transaction().await;
match transaction {
Ok(transaction_ok) => {
self.transaction = Some(transaction_ok);
Ok(())
}
Err(e) => Err(anyhow::anyhow!("Error starting transaction: {}", e))
}
}
pub async fn commit(&'a mut self) -> Result<()> {
match &mut self.transaction {
Some(transaction) => {
transaction.commit().await?;
Ok(())
}
None => Err(anyhow::anyhow!("No transaction to commit"))
}
}
}
}