dotenvy/
errors.rs

1use std::env;
2use std::error;
3use std::fmt;
4use std::io;
5
6pub type Result<T> = std::result::Result<T, Error>;
7
8#[derive(Debug)]
9#[non_exhaustive]
10pub enum Error {
11    LineParse(String, usize),
12    Io(io::Error),
13    EnvVar(env::VarError),
14}
15
16impl Error {
17    pub fn not_found(&self) -> bool {
18        if let Error::Io(ref io_error) = *self {
19            return io_error.kind() == io::ErrorKind::NotFound;
20        }
21        false
22    }
23}
24
25impl error::Error for Error {
26    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
27        match self {
28            Error::Io(err) => Some(err),
29            Error::EnvVar(err) => Some(err),
30            _ => None,
31        }
32    }
33}
34
35impl fmt::Display for Error {
36    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
37        match self {
38            Error::Io(err) => write!(fmt, "{}", err),
39            Error::EnvVar(err) => write!(fmt, "{}", err),
40            Error::LineParse(line, error_index) => write!(
41                fmt,
42                "Error parsing line: '{}', error at line index: {}",
43                line, error_index
44            ),
45        }
46    }
47}
48
49#[cfg(test)]
50mod test {
51    use std::env;
52    use std::error::Error as StdError;
53    use std::io;
54
55    use super::*;
56
57    #[test]
58    fn test_io_error_source() {
59        let err = Error::Io(io::ErrorKind::PermissionDenied.into());
60        let io_err = err.source().unwrap().downcast_ref::<io::Error>().unwrap();
61        assert_eq!(io::ErrorKind::PermissionDenied, io_err.kind());
62    }
63
64    #[test]
65    fn test_envvar_error_source() {
66        let err = Error::EnvVar(env::VarError::NotPresent);
67        let var_err = err
68            .source()
69            .unwrap()
70            .downcast_ref::<env::VarError>()
71            .unwrap();
72        assert_eq!(&env::VarError::NotPresent, var_err);
73    }
74
75    #[test]
76    fn test_lineparse_error_source() {
77        let err = Error::LineParse("test line".to_string(), 2);
78        assert!(err.source().is_none());
79    }
80
81    #[test]
82    fn test_error_not_found_true() {
83        let err = Error::Io(io::ErrorKind::NotFound.into());
84        assert!(err.not_found());
85    }
86
87    #[test]
88    fn test_error_not_found_false() {
89        let err = Error::Io(io::ErrorKind::PermissionDenied.into());
90        assert!(!err.not_found());
91    }
92
93    #[test]
94    fn test_io_error_display() {
95        let err = Error::Io(io::ErrorKind::PermissionDenied.into());
96        let io_err: io::Error = io::ErrorKind::PermissionDenied.into();
97
98        let err_desc = format!("{}", err);
99        let io_err_desc = format!("{}", io_err);
100        assert_eq!(io_err_desc, err_desc);
101    }
102
103    #[test]
104    fn test_envvar_error_display() {
105        let err = Error::EnvVar(env::VarError::NotPresent);
106        let var_err = env::VarError::NotPresent;
107
108        let err_desc = format!("{}", err);
109        let var_err_desc = format!("{}", var_err);
110        assert_eq!(var_err_desc, err_desc);
111    }
112
113    #[test]
114    fn test_lineparse_error_display() {
115        let err = Error::LineParse("test line".to_string(), 2);
116        let err_desc = format!("{}", err);
117        assert_eq!(
118            "Error parsing line: 'test line', error at line index: 2",
119            err_desc
120        );
121    }
122}