1#![no_std]
4#![forbid(unsafe_code)]
5#![warn(missing_docs)]
6
7pub trait BoolExt {
9 fn and<T>(self, value: Option<T>) -> Option<T>;
11
12 fn and_some<T>(self, value: T) -> Option<T>;
14
15 fn and_then<T>(self, f: impl FnOnce() -> Option<T>) -> Option<T>;
17
18 fn and_then_some<T>(self, f: impl FnOnce() -> T) -> Option<T>;
20}
21
22impl BoolExt for bool {
23 fn and<T>(self, value: Option<T>) -> Option<T> {
24 if self { value } else { None }
25 }
26
27 fn and_some<T>(self, value: T) -> Option<T> {
28 if self { Some(value) } else { None }
29 }
30
31 fn and_then<T>(self, f: impl FnOnce() -> Option<T>) -> Option<T> {
32 if self { f() } else { None }
33 }
34
35 fn and_then_some<T>(self, f: impl FnOnce() -> T) -> Option<T> {
36 if self { Some(f()) } else { None }
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::BoolExt;
43
44 #[test]
45 fn and() {
46 assert_eq!(true.and(Some("hello")), Some("hello"));
47 assert_eq!(true.and(Option::<&str>::None), None);
48 assert_eq!(false.and(Some("world")), None);
49 assert_eq!(false.and(Option::<&str>::None), None);
50 }
51
52 #[test]
53 fn and_some() {
54 assert_eq!(true.and_some(()), Some(()));
55 assert_eq!(false.and_some(()), None);
56 }
57
58 #[test]
59 fn and_then() {
60 assert_eq!(true.and_then(|| Some(1 + 1)), Some(2));
61 assert_eq!(true.and_then(|| Option::<u32>::None), None);
62 assert_eq!(false.and_then(|| Some(1 + 1)), None);
63 assert_eq!(false.and_then(|| Option::<u32>::None), None);
64 }
65
66 #[test]
67 fn and_then_some() {
68 assert_eq!(true.and_then_some(|| true), Some(true));
69 assert_eq!(true.and_then_some(|| false), Some(false));
70 assert_eq!(false.and_then_some(|| true), None);
71 assert_eq!(false.and_then_some(|| false), None);
72 }
73
74 #[test]
75 fn side_effects() {
76 let mut ct = 0;
77
78 let _ = true.and_then(|| {
79 ct += 1;
80 Some(())
81 });
82 assert_eq!(ct, 1);
83
84 let _ = false.and_then(|| {
85 ct += 1;
86 Some(())
87 });
88 assert_eq!(ct, 1);
89
90 let _ = true.and_then_some(|| ct += 1);
91 assert_eq!(ct, 2);
92
93 let _ = false.and_then_some(|| ct += 1);
94 assert_eq!(ct, 2);
95 }
96}