1use std::{convert::Infallible, error, fmt};
2
3#[derive(Debug)]
4pub enum Error {
5 R2D2(r2d2::Error),
6
7 PostgreSQL(postgres::Error),
8 SQLite(rusqlite::Error),
9
10 NoSqlQueryProvided,
11 QueryReturnedNoRows,
12 MismatchedColumnCount,
13}
14
15impl fmt::Display for Error {
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 match self {
18 Error::R2D2(err) => write!(f, "{}", err),
19
20 Error::PostgreSQL(err) => write!(f, "{}", err),
21 Error::SQLite(err) => write!(f, "{}", err),
22
23 Error::NoSqlQueryProvided => write!(
24 f,
25 "a sql query was not given to the type, this should not happen"
26 ),
27 Error::QueryReturnedNoRows => write!(f, "a sql query returned no rows"),
28 Error::MismatchedColumnCount => write!(
29 f,
30 "the given type and the returning query do not have the same amount of columns"
31 ),
32 }
33 }
34}
35
36impl error::Error for Error {
37 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
38 match self {
39 Error::R2D2(err) => Some(err),
40
41 Error::PostgreSQL(err) => Some(err),
42 Error::SQLite(err) => Some(err),
43
44 Error::NoSqlQueryProvided => None,
45 Error::QueryReturnedNoRows => None,
46 Error::MismatchedColumnCount => None,
47 }
48 }
49}
50
51impl From<r2d2::Error> for Error {
52 fn from(err: r2d2::Error) -> Error {
53 Error::R2D2(err)
54 }
55}
56
57impl From<postgres::Error> for Error {
58 fn from(err: postgres::Error) -> Error {
59 Error::PostgreSQL(err)
60 }
61}
62
63impl From<rusqlite::Error> for Error {
64 fn from(err: rusqlite::Error) -> Error {
65 Error::SQLite(err)
66 }
67}
68
69impl From<Infallible> for Error {
70 fn from(_: Infallible) -> Self {
71 unreachable!()
72 }
73}
74
75pub trait OptionalExtension<T> {
76 fn optional(self) -> Result<Option<T>, Error>;
77}
78
79impl<T> OptionalExtension<T> for Result<T, Error> {
80 fn optional(self) -> Result<Option<T>, Error> {
81 match self {
82 Ok(value) => Ok(Some(value)),
83 Err(Error::QueryReturnedNoRows) => Ok(None),
84 Err(e) => Err(e),
85 }
86 }
87}