libmrot/
error.rs

1//! Mrot error
2
3use confy::ConfyError;
4use sqlite::Error as SqliteError;
5use std::{convert::From, ffi::OsString, fmt, io::Error as IoError, num::ParseIntError};
6use two_timer::TimeError;
7
8/// Mrot error variants
9#[derive(Debug)]
10pub enum Error {
11    /// wraps [std::io::Error]
12    Io(IoError),
13    /// wraps [confy::ConfyError]
14    Confy(ConfyError),
15    /// wraps [sqlite::Error]
16    Sqlite(SqliteError),
17    /// wraps [std::fmt::Error]
18    Fmt(fmt::Error),
19    /// wraps [two_timer::TimeError]
20    TwoTimer(TimeError),
21    /// when a [chrono::NaiveDate] cannot be converted to [chrono::NaiveDateTime]
22    TimeNotSupported,
23    /// when a path contains an invalid Unicode character
24    InvalidUnicode(OsString),
25    /// when [directories::ProjectDirs] is not found
26    NoDirectory(String),
27    /// when a path does not have a parent directory
28    NoParentDirectory,
29    /// Timestamp cannot be converted into [chrono::DateTime]
30    InvalidTimestamp(i64),
31    /// Wraps [std::num::ParseIntError]
32    StdNum(ParseIntError),
33    /// when [MealRecord] cannot be parsed
34    ParseMealRecordError,
35}
36
37impl fmt::Display for Error {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        match &self {
40            Error::Io(io_error) => fmt::Display::fmt(io_error, f),
41            Error::Confy(confy_error) => fmt::Display::fmt(confy_error, f),
42            Error::Sqlite(sqlite_error) => fmt::Display::fmt(sqlite_error, f),
43            Error::Fmt(fmt_error) => fmt::Display::fmt(fmt_error, f),
44            Error::TwoTimer(time_error) => fmt::Display::fmt(time_error, f),
45            Error::TimeNotSupported => fmt::Display::fmt("such time is not supported", f),
46            Error::InvalidUnicode(os_string) => fmt::Display::fmt(
47                &format!(
48                    "invalid Unicode string: {}",
49                    os_string.to_string_lossy().into_owned().as_str()
50                ),
51                f,
52            ),
53            Error::NoDirectory(group) => {
54                fmt::Display::fmt(&format!("cannot find directory for {}", group), f)
55            }
56            Error::NoParentDirectory => fmt::Display::fmt("cannot find parent directory", f),
57            Error::InvalidTimestamp(i) => fmt::Display::fmt(&format!("invalid timestamp {}", i), f),
58            Error::StdNum(parse_int_error) => fmt::Display::fmt(parse_int_error, f),
59            Error::ParseMealRecordError => fmt::Display::fmt("cannot parse MealRecord", f),
60        }
61    }
62}
63
64impl std::error::Error for Error {
65    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
66        match *self {
67            Error::Io(ref io_error) => Some(io_error),
68            Error::Confy(ref confy_error) => Some(confy_error),
69            Error::Sqlite(ref sqlite_error) => Some(sqlite_error),
70            Error::Fmt(ref fmt_error) => Some(fmt_error),
71            Error::TwoTimer(ref time_error) => Some(time_error),
72            Error::TimeNotSupported => None,
73            Error::InvalidUnicode(_) => None,
74            Error::NoDirectory(_) => None,
75            Error::NoParentDirectory => None,
76            Error::InvalidTimestamp(_) => None,
77            Error::StdNum(ref parse_int_error) => Some(parse_int_error),
78            Error::ParseMealRecordError => None,
79        }
80    }
81}
82
83impl From<IoError> for Error {
84    fn from(value: IoError) -> Self {
85        Error::Io(value)
86    }
87}
88
89impl From<ConfyError> for Error {
90    fn from(value: ConfyError) -> Self {
91        Error::Confy(value)
92    }
93}
94
95impl From<OsString> for Error {
96    fn from(value: OsString) -> Self {
97        Error::InvalidUnicode(value)
98    }
99}
100
101impl From<SqliteError> for Error {
102    fn from(value: SqliteError) -> Self {
103        Error::Sqlite(value)
104    }
105}
106
107impl From<fmt::Error> for Error {
108    fn from(value: fmt::Error) -> Self {
109        Error::Fmt(value)
110    }
111}
112
113impl From<TimeError> for Error {
114    fn from(value: TimeError) -> Self {
115        Error::TwoTimer(value)
116    }
117}
118
119impl From<ParseIntError> for Error {
120    fn from(value: ParseIntError) -> Self {
121        Error::StdNum(value)
122    }
123}