db-derive 0.1.8

PostgreSQL/SQLite pooling derive system
Documentation
use {
    crate::{table::Schema, Error, Pool},
    std::convert::{TryFrom, TryInto},
};

pub enum Connection {
    #[cfg(feature = "postgresql")]
    PostgreSQL(
        r2d2::PooledConnection<crate::pool::postgres::PostgresConnectionManager<postgres::NoTls>>,
    ),
    #[cfg(feature = "sqlite")]
    SQLite(r2d2::PooledConnection<crate::pool::sqlite::SqliteConnectionManager>),
}

impl TryFrom<Pool> for Connection {
    type Error = Error;

    fn try_from(pool: Pool) -> Result<Connection, Self::Error> {
        match pool {
            #[cfg(feature = "postgresql")]
            Pool::PostgreSQL(pool) => {
                let conn = pool.get()?;

                Ok(Connection::PostgreSQL(conn))
            }
            #[cfg(feature = "sqlite")]
            Pool::SQLite(pool) => {
                let conn = pool.get()?;

                Ok(Connection::SQLite(conn))
            }
        }
    }
}

impl<'r> TryFrom<&'r Pool> for Connection {
    type Error = Error;

    fn try_from(pool: &'r Pool) -> Result<Connection, Self::Error> {
        match pool {
            #[cfg(feature = "postgresql")]
            Pool::PostgreSQL(pool) => {
                let conn = pool.get()?;

                Ok(Connection::PostgreSQL(conn))
            }
            #[cfg(feature = "sqlite")]
            Pool::SQLite(pool) => {
                let conn = pool.get()?;

                Ok(Connection::SQLite(conn))
            }
        }
    }
}

pub enum Transaction<'r> {
    #[cfg(feature = "postgresql")]
    PostgreSQL(postgres::Transaction<'r>),
    #[cfg(feature = "sqlite")]
    SQLite(rusqlite::Transaction<'r>),
}

impl<'r> Transaction<'r> {
    pub fn schema<T: Schema>(&mut self) -> Result<(), Error> {
        match self {
            #[cfg(feature = "postgresql")]
            Transaction::PostgreSQL(ref mut trans) => {
                trans.batch_execute(T::schema_postgres())?;
            }
            #[cfg(feature = "sqlite")]
            Transaction::SQLite(trans) => {
                trans.execute_batch(T::schema_sqlite())?;
            }
        }

        Ok(())
    }
}

pub enum Row<'r> {
    #[cfg(feature = "postgresql")]
    PostgreSQL(postgres::Row),
    #[cfg(feature = "sqlite")]
    SQLite(&'r rusqlite::Row<'r>),
}

// TODO: fix clippy warning
// Clippy says the SQLite variant is too large and to box it
// However it would be created every time a connection is made
#[allow(clippy::large_enum_variant)]
pub enum ConnTrans<'r> {
    Conn(Connection),
    Trans(Transaction<'r>),
}

impl<'r> TryFrom<Pool> for ConnTrans<'r> {
    type Error = Error;

    fn try_from(pool: Pool) -> Result<ConnTrans<'r>, Error> {
        let conn = pool.try_into()?;

        Ok(ConnTrans::Conn(conn))
    }
}

impl<'r> TryFrom<&'r Pool> for ConnTrans<'r> {
    type Error = Error;

    fn try_from(pool: &'r Pool) -> Result<ConnTrans<'r>, Error> {
        let conn = pool.try_into()?;

        Ok(ConnTrans::Conn(conn))
    }
}

impl<'r> From<Connection> for ConnTrans<'r> {
    fn from(conn: Connection) -> ConnTrans<'r> {
        ConnTrans::Conn(conn)
    }
}

impl<'r> From<Transaction<'r>> for ConnTrans<'r> {
    fn from(trans: Transaction<'r>) -> ConnTrans<'r> {
        ConnTrans::Trans(trans)
    }
}