dotenv_flow/
errors.rs

1use std::error;
2use std::fmt;
3use std::io;
4
5pub type Result<T> = std::result::Result<T, Error>;
6
7#[derive(Debug)]
8pub enum Error {
9    LineParse(String, usize),
10    Io(io::Error),
11    EnvVar(std::env::VarError),
12    #[doc(hidden)]
13    __Nonexhaustive,
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            _ => unreachable!(),
46        }
47    }
48}
49
50#[cfg(test)]
51mod test {
52    use std::error::Error as StdError;
53
54    use super::*;
55
56    #[test]
57    fn test_io_error_source() {
58        let err = Error::Io(std::io::ErrorKind::PermissionDenied.into());
59        let io_err = err
60            .source()
61            .unwrap()
62            .downcast_ref::<std::io::Error>()
63            .unwrap();
64        assert_eq!(std::io::ErrorKind::PermissionDenied, io_err.kind());
65    }
66
67    #[test]
68    fn test_envvar_error_source() {
69        let err = Error::EnvVar(std::env::VarError::NotPresent);
70        let var_err = err
71            .source()
72            .unwrap()
73            .downcast_ref::<std::env::VarError>()
74            .unwrap();
75        assert_eq!(&std::env::VarError::NotPresent, var_err);
76    }
77
78    #[test]
79    fn test_lineparse_error_source() {
80        let err = Error::LineParse("test line".to_string(), 2);
81        assert!(err.source().is_none());
82    }
83
84    #[test]
85    fn test_error_not_found_true() {
86        let err = Error::Io(std::io::ErrorKind::NotFound.into());
87        assert!(err.not_found());
88    }
89
90    #[test]
91    fn test_error_not_found_false() {
92        let err = Error::Io(std::io::ErrorKind::PermissionDenied.into());
93        assert!(!err.not_found());
94    }
95
96    #[test]
97    fn test_io_error_display() {
98        let err = Error::Io(std::io::ErrorKind::PermissionDenied.into());
99        let io_err: std::io::Error = std::io::ErrorKind::PermissionDenied.into();
100
101        let err_desc = format!("{}", err);
102        let io_err_desc = format!("{}", io_err);
103        assert_eq!(io_err_desc, err_desc);
104    }
105
106    #[test]
107    fn test_envvar_error_display() {
108        let err = Error::EnvVar(std::env::VarError::NotPresent);
109        let var_err = std::env::VarError::NotPresent;
110
111        let err_desc = format!("{}", err);
112        let var_err_desc = format!("{}", var_err);
113        assert_eq!(var_err_desc, err_desc);
114    }
115
116    #[test]
117    fn test_lineparse_error_display() {
118        let err = Error::LineParse("test line".to_string(), 2);
119        let err_desc = format!("{}", err);
120        assert_eq!(
121            "Error parsing line: 'test line', error at line index: 2",
122            err_desc
123        );
124    }
125}