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),
}
}
}