errors_with_context/
boolean.rs

1use crate::ErrorMessage;
2
3/// This trait allows one to turn [bools](bool) into [ErrorMessages](ErrorMessage),
4/// when they have a certain value.
5///
6/// This allows for cool code like this:
7/// ```rust
8/// # use std::path::Path;
9/// use errors_with_context::{BooleanErrors, ErrorMessage};
10/// # fn func() -> Result<(), ErrorMessage> {
11/// let path = Path::new("test.file");
12/// path.exists()
13///     .error_if_false("Expected file to exist!")?;
14/// #   Ok(())
15/// # }
16/// # fn main() {
17/// #     let  string = func().unwrap_err().to_string();
18/// #     assert_eq!(string, "Expected file to exist!");
19/// # }
20/// ```
21/// or with more dynamic context:
22/// ```rust
23/// # use std::path::Path;
24/// use errors_with_context::prelude::*;
25/// # fn func() -> Result<(), ErrorMessage> {
26/// let path = Path::new("test.file");
27/// path.exists()
28///     .error_dyn_if_false(|| format!("Expected file '{}' to exist!", path.display()))?;
29/// #   Ok(())
30/// # }
31/// # fn main() {
32/// #     let  string = func().unwrap_err().to_string();
33/// #     assert_eq!(string, "Expected file 'test.file' to exist!");
34/// # }
35/// ```
36///
37/// Very useful, when doing lots of checks that aren't immediately errors.
38pub trait BooleanErrors {
39    /// If the [bool] is true, return it `Ok(bool)`.  
40    /// If the [bool] is false, return an `Err(ErrorMessage)` with the provided context string..
41    ///
42    /// ```rust
43    /// # use std::path::Path;
44    /// use errors_with_context::prelude::*;
45    /// # fn func() -> Result<(), ErrorMessage> {
46    /// let path = Path::new("test.file");
47    /// path.exists()
48    ///     .error_if_false("Expected file to exist!")?;
49    /// #   Ok(())
50    /// # }
51    /// # fn main() {
52    /// #     let  string = func().unwrap_err().to_string();
53    /// #     assert_eq!(string, "Expected file to exist!");
54    /// # }
55    /// ```
56    fn error_if_false(self, context: impl AsRef<str>) -> Result<bool, ErrorMessage>;
57
58    /// If the [bool] is false, return it wrapped in a `Ok(bool)`.  
59    /// If the [bool] is true, return an `Err(ErrorMessage)` with the provided context string.
60    ///
61    /// ```rust
62    /// # use std::path::Path;
63    /// # use std::ops::Not;
64    /// use errors_with_context::prelude::*;
65    /// # fn func() -> Result<(), ErrorMessage> {
66    /// let path = Path::new("test.file");
67    /// path.exists()
68    ///     .not()
69    ///     .error_if_true("Expected file to exist!")?;
70    /// #   Ok(())
71    /// # }
72    /// # fn main() {
73    /// #     let  string = func().unwrap_err().to_string();
74    /// #     assert_eq!(string, "Expected file to exist!");
75    /// # }
76    /// ```
77    fn error_if_true(self, context: impl AsRef<str>) -> Result<bool, ErrorMessage>;
78
79    /// If the [bool] is true, return it `Ok(bool)`.  
80    /// If the [bool] is false, compute the context and return an `Err(ErrorMessage)`.
81    ///
82    /// ```rust
83    /// # use std::path::Path;
84    /// use errors_with_context::prelude::*;
85    /// # fn func() -> Result<(), ErrorMessage> {
86    /// let path = Path::new("test.file");
87    /// path.exists()
88    ///     .error_dyn_if_false(|| format!("Expected file '{}' to exist!", path.display()))?;
89    /// #   Ok(())
90    /// # }
91    /// # fn main() {
92    /// #     let  string = func().unwrap_err().to_string();
93    /// #     assert_eq!(string, "Expected file 'test.file' to exist!");
94    /// # }
95    fn error_dyn_if_false(self, context: impl FnOnce() -> String) -> Result<bool, ErrorMessage>;
96
97    /// If the [bool] is false, return it `Ok(bool)`.  
98    /// If the [bool] is true, compute the context and return an `Err(ErrorMessage)`.
99    ///
100    /// ```rust
101    /// # use std::path::Path;
102    /// # use std::ops::Not;
103    /// use errors_with_context::prelude::*;
104    /// # fn func() -> Result<(), ErrorMessage> {
105    /// let path = Path::new("test.file");
106    /// path.exists()
107    ///     .not()
108    ///     .error_dyn_if_true(|| format!("Expected file '{}' to exist!", path.display()))?;
109    /// #   Ok(())
110    /// # }
111    /// # fn main() {
112    /// #     let  string = func().unwrap_err().to_string();
113    /// #     assert_eq!(string, "Expected file 'test.file' to exist!");
114    /// # }
115    fn error_dyn_if_true(self, context: impl FnOnce() -> String) -> Result<bool, ErrorMessage>;
116}
117
118impl BooleanErrors for bool {
119    fn error_if_false(self, context: impl AsRef<str>) -> Result<bool, ErrorMessage> {
120        if self {
121            Ok(self)
122        } else {
123            Err(ErrorMessage::new(context.as_ref()))
124        }
125    }
126
127    fn error_if_true(self, context: impl AsRef<str>) -> Result<bool, ErrorMessage> {
128        if self {
129            Err(ErrorMessage::new(context.as_ref()))
130        } else {
131            Ok(self)
132        }
133    }
134
135    fn error_dyn_if_false(self, context: impl FnOnce() -> String) -> Result<bool, ErrorMessage> {
136        if self {
137            Ok(self)
138        } else {
139            Err(ErrorMessage::new(context()))
140        }
141    }
142
143    fn error_dyn_if_true(self, context: impl FnOnce() -> String) -> Result<bool, ErrorMessage> {
144        if self {
145            Err(ErrorMessage::new(context()))
146        } else {
147            Ok(self)
148        }
149    }
150}