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