db-derive 0.1.8

PostgreSQL/SQLite pooling derive system
Documentation
use std::{convert::Infallible, error, fmt};

#[derive(Debug)]
pub enum Error {
    R2D2(r2d2::Error),

    PostgreSQL(postgres::Error),
    SQLite(rusqlite::Error),

    NoSqlQueryProvided,
    QueryReturnedNoRows,
    MismatchedColumnCount,
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Error::R2D2(err) => write!(f, "{}", err),

            Error::PostgreSQL(err) => write!(f, "{}", err),
            Error::SQLite(err) => write!(f, "{}", err),

            Error::NoSqlQueryProvided => write!(
                f,
                "a sql query was not given to the type, this should not happen"
            ),
            Error::QueryReturnedNoRows => write!(f, "a sql query returned no rows"),
            Error::MismatchedColumnCount => write!(
                f,
                "the given type and the returning query do not have the same amount of columns"
            ),
        }
    }
}

impl error::Error for Error {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match self {
            Error::R2D2(err) => Some(err),

            Error::PostgreSQL(err) => Some(err),
            Error::SQLite(err) => Some(err),

            Error::NoSqlQueryProvided => None,
            Error::QueryReturnedNoRows => None,
            Error::MismatchedColumnCount => None,
        }
    }
}

impl From<r2d2::Error> for Error {
    fn from(err: r2d2::Error) -> Error {
        Error::R2D2(err)
    }
}

impl From<postgres::Error> for Error {
    fn from(err: postgres::Error) -> Error {
        Error::PostgreSQL(err)
    }
}

impl From<rusqlite::Error> for Error {
    fn from(err: rusqlite::Error) -> Error {
        Error::SQLite(err)
    }
}

impl From<Infallible> for Error {
    fn from(_: Infallible) -> Self {
        unreachable!()
    }
}

pub trait OptionalExtension<T> {
    fn optional(self) -> Result<Option<T>, Error>;
}

impl<T> OptionalExtension<T> for Result<T, Error> {
    fn optional(self) -> Result<Option<T>, Error> {
        match self {
            Ok(value) => Ok(Some(value)),
            Err(Error::QueryReturnedNoRows) => Ok(None),
            Err(e) => Err(e),
        }
    }
}