testutils/bool_ext.rs
1//! Extension trait for types that can be converted into a bool.
2pub trait BoolExt {
3 /// Converts the bool value into a `Result<(), E>`.
4 ///
5 /// If the value is `true`, it returns `Ok(())`. If the value is `false`, it
6 /// returns `Err(err())`.
7 ///
8 /// # Examples
9 ///
10 /// ## Simple
11 ///
12 /// ```
13 /// use testutils::bool_ext::BoolExt;
14 ///
15 /// let value = true;
16 /// let res: Result<(), &str> = value.then_ok_or_else(|| "error");
17 /// assert_eq!(res, Ok(()));
18 ///
19 /// let value = false;
20 /// assert_eq!(value.then_ok_or_else(|| "error"), Err("error"));
21 /// ```
22 ///
23 /// ## A more complex example
24 ///
25 /// ```ignore
26 /// use testutils::tap::Pipe;
27 /// use testutils::get_pkg_name;
28 /// use testutils::testutils::bool_ext::BoolExt;
29 /// use std::io;
30 ///
31 /// let err = || "Failed to run `cargo rustdoc` command".pipe(io::Error::other);
32 ///
33 /// get_pkg_name!()
34 /// .pipe(build_rsdoc)? // ExitStatus
35 /// .success() // bool
36 /// .then_ok_or_else(err) // io::Result<()>
37 /// ```
38 fn then_ok_or_else<E>(self, err_fn: impl FnOnce() -> E) -> Result<(), E>
39 where
40 Self: Into<bool>,
41 {
42 if self.into() { Ok(()) } else { Err(err_fn()) }
43 }
44
45 fn then_ok_or<E>(self, err: E) -> Result<(), E>
46 where
47 Self: Into<bool>,
48 {
49 if self.into() { Ok(()) } else { Err(err) }
50 }
51}
52
53impl BoolExt for bool {}
54
55#[cfg(test)]
56mod tests {
57 use tap::TapOptional;
58
59 use super::*;
60
61 #[ignore]
62 #[test]
63 fn test_tap_opt() {
64 let opt = Some(42);
65 opt.tap_some(|&x| assert_eq!(x, 42));
66 opt.map(|x| assert_eq!(x, 42));
67 }
68
69 #[ignore]
70 #[test]
71 fn test_bool_ok_or_else() {
72 let value = true;
73 let res: Result<(), &str> = value.then_ok_or_else(|| "error");
74 assert_eq!(res, Ok(()));
75
76 let value = false;
77 assert_eq!(value.then_ok_or_else(|| "error"), Err("error"));
78 }
79
80 #[cfg(feature = "std")]
81 #[ignore]
82 #[test]
83 fn test_bool_ok_or_std_io_error() {
84 // use std::io;
85 }
86}