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}