pub trait ClientBorrowMut {
// Required method
fn _borrow_mut(&mut self) -> &mut Client;
}Expand description
a marker trait to confirm a mut reference of Client can be borrowed from self.
this is necessary for custom Client new types who want to utilize Transaction and CopyIn. these types and their functions only work properly when Client is exclusively borrowed.
§Examples
use std::sync::Arc;
use xitca_postgres::{dev::ClientBorrowMut, transaction::TransactionBuilder, Client, Error};
// a client wrapper use reference counted smart pointer.
// it's easy to create multiple instance of &mut SharedClient with help of cloning of smart pointer
// and none of them can be used correctly with Transaction nor CopyIn
#[derive(Clone)]
struct SharedClient(Arc<Client>);
// client new type has to impl this trait to mark they can truly offer a mutable reference to Client
//
impl ClientBorrowMut for SharedClient {
fn _borrow_mut(&mut self) -> &mut Client {
Arc::get_mut(&mut self.0).expect("you can't safely implement this trait with SharedClient.")
}
}
async fn borrow_mut(cli: Client) -> Result<(), Error> {
let mut cli = SharedClient(Arc::new(cli));
// this line works fine as shared client is exclusivly borrowed by transaction
let _ = TransactionBuilder::new().begin(&mut cli).await?;
// clone shared client before starting a transaction.
let _cli2 = cli.clone();
// this line will panic as shared client has another copy being held by cli2 varaiable
let _ = TransactionBuilder::new().begin(&mut cli).await?;
Ok(())
}