human_errors/
option.rs

1use std::borrow::Cow;
2
3use super::*;
4
5/// Extension trait for `Option` to convert `None` values into user-friendly 
6/// error types.
7/// 
8/// # Examples
9/// ```
10/// use human_errors::OptionExt;
11/// 
12/// // Converts a `None` value into a user-caused error with the provided message and advice.
13/// let value = None::<i32>.ok_or_user_err(
14///    "No value was provided.",
15///    &["Please provide a valid integer value."],
16/// );
17/// 
18/// // Converts a `None` value into a system-caused error with the provided message and advice.
19/// let value = None::<i32>.ok_or_system_err(
20///   "No value was provided.",
21///   &["Please check your system configuration."],
22/// );
23/// ```
24pub trait OptionExt<T> {
25    /// Converts an `Option<T>` into a `Result<T, Error>`, returning a user-caused
26    /// error with the provided message and advice if the option is `None`.
27    ///
28    /// # Examples
29    /// ```
30    /// use human_errors::OptionExt;
31    /// 
32    /// let value = None::<i32>.ok_or_user_err(
33    ///   "No value was provided.",
34    ///   &["Please provide a valid integer value."],
35    /// );
36    /// ```
37    fn ok_or_user_err<S: Into<Cow<'static, str>>>(self, msg: S, advice: &'static [&'static str]) -> Result<T, Error>;
38
39    /// Converts an `Option<T>` into a `Result<T, Error>`, returning a system-caused
40    /// error with the provided message and advice if the option is `None`.
41    /// 
42    /// # Examples
43    /// ```
44    /// use human_errors::OptionExt;
45    /// 
46    /// let value = None::<i32>.ok_or_system_err(
47    ///   "No value was provided.",
48    ///   &["Please check your system configuration."], 
49    /// );
50    /// ```
51    fn ok_or_system_err<S: Into<Cow<'static, str>>>(self, msg: S, advice: &'static [&'static str]) -> Result<T, Error>;
52}
53
54impl <T> OptionExt<T> for Option<T> {
55    fn ok_or_user_err<S: Into<Cow<'static, str>>>(self, msg: S, advice: &'static [&'static str]) -> Result<T, Error> {
56        match self {
57            Some(value) => Ok(value),
58            None => Err(user(msg.into(), advice)),
59        }
60    }
61
62    fn ok_or_system_err<S: Into<Cow<'static, str>>>(self, msg: S, advice: &'static [&'static str]) -> Result<T, Error> {
63        match self {
64            Some(value) => Ok(value),
65            None => Err(system(msg.into(), advice)),
66        }
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn test_ok_or_user_err_some() {
76        let value = Some(42).ok_or_user_err("No value", &["Provide a value"]).unwrap();
77        assert_eq!(value, 42);
78    }
79
80    #[test]
81    fn test_ok_or_user_err_none() {
82        let err = None::<i32>.ok_or_user_err("No value", &["Provide a value"]).unwrap_err();
83        assert!(err.is(Kind::User));
84        assert_eq!(err.message(), "No value");
85    }
86
87    #[test]
88    fn test_ok_or_system_err_some() {
89        let value = Some(42).ok_or_system_err("No value", &["Check system"]).unwrap();
90        assert_eq!(value, 42);
91    }
92
93    #[test]
94    fn test_ok_or_system_err_none() {
95        let err = None::<i32>.ok_or_system_err("No value", &["Check system"]).unwrap_err();
96        assert!(err.is(Kind::System));
97        assert_eq!(err.message(), "No value");
98    }
99}