use std::marker::PhantomData;
use sqlx::{pool::PoolConnection, Sqlite, SqliteConnection};
use super::{magic::*, Connection};
pub struct Conn<Writable: Bool, Tx = NoTransaction> {
inner: InnerConn<Tx>,
_type: PhantomData<Writable>,
}
impl<W: Bool> Conn<W> {
pub(super) fn new(inner: PoolConnection<Sqlite>) -> Conn<W> {
Conn {
inner: InnerConn::Pool(inner),
_type: PhantomData,
}
}
pub(super) fn from_tx<'tx, 'conn>(
inner: &'tx mut sqlx::Transaction<'conn, sqlx::Sqlite>,
) -> Conn<W, Tx<'tx, 'conn>> {
Conn {
inner: InnerConn::InTransaction(Tx(inner)),
_type: PhantomData,
}
}
}
pub type Writer<Tx> = Conn<True, Tx>;
pub type Reader<Tx> = Conn<False, Tx>;
pub struct Tx<'tx, 'conn>(&'tx mut sqlx::Transaction<'conn, sqlx::Sqlite>);
pub enum NoTransaction {}
impl<Writable> Connection for Conn<Writable, NoTransaction>
where
Writable: Bool,
{
type Writable = Writable;
type Transaction = False;
fn get_inner(&mut self) -> &mut SqliteConnection {
match &mut self.inner {
InnerConn::Pool(pool_connection) => pool_connection,
InnerConn::InTransaction(_) => unreachable!(),
}
}
}
impl<Writable> Connection for Conn<Writable, Tx<'_, '_>>
where
Writable: Bool,
{
type Writable = Writable;
type Transaction = True;
fn get_inner(&mut self) -> &mut SqliteConnection {
match &mut self.inner {
InnerConn::Pool(pool_connection) => pool_connection,
InnerConn::InTransaction(transaction) => transaction.0,
}
}
}
#[derive(Debug)]
enum InnerConn<Tx> {
Pool(PoolConnection<Sqlite>),
InTransaction(Tx),
}