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}