1use futures::future::OptionFuture;
4
5pub trait BoolExt {
7 fn and<T>(self, t: Option<T>) -> Option<T>;
8
9 #[must_use]
10 fn and_is(self, b: bool) -> bool;
11
12 #[must_use]
13 fn and_if<F: FnOnce() -> bool>(self, f: F) -> bool;
14
15 fn and_then<T, F: FnOnce() -> Option<T>>(self, f: F) -> Option<T>;
16
17 #[must_use]
18 fn clone_or<T: Clone>(self, err: T, t: &T) -> T;
19
20 #[must_use]
21 fn copy_or<T: Copy>(self, err: T, t: T) -> T;
22
23 #[must_use]
24 fn expect(self, msg: &str) -> Self;
25
26 #[must_use]
27 fn expect_false(self, msg: &str) -> Self;
28
29 fn into_option(self) -> Option<()>;
30
31 #[expect(clippy::result_unit_err)]
32 fn into_result(self) -> Result<(), ()>;
33
34 #[must_use]
35 fn is_false(&self) -> Self;
36
37 fn map<T, F: FnOnce(Self) -> T>(self, f: F) -> T
38 where
39 Self: Sized;
40
41 fn map_ok_or<T, E, F: FnOnce() -> T>(self, err: E, f: F) -> Result<T, E>;
42
43 fn map_or<T, F: FnOnce() -> T>(self, err: T, f: F) -> T;
44
45 fn map_or_else<T, E: FnOnce() -> T, F: FnOnce() -> T>(self, err: E, f: F) -> T;
46
47 fn ok_or<E>(self, err: E) -> Result<(), E>;
48
49 fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<(), E>;
50
51 fn or<T, F: FnOnce() -> T>(self, f: F) -> Option<T>;
52
53 fn or_some<T>(self, t: T) -> Option<T>;
54
55 fn then_async<O: Future, F: FnOnce() -> O>(self, f: F) -> OptionFuture<O>;
56
57 fn then_none<T>(self) -> Option<T>;
58
59 fn then_ok_or<T, E>(self, t: T, e: E) -> Result<T, E>;
60
61 fn then_ok_or_else<T, E, F: FnOnce() -> E>(self, t: T, e: F) -> Result<T, E>;
62}
63
64impl BoolExt for bool {
65 #[inline]
66 fn and<T>(self, t: Option<T>) -> Option<T> { self.then_some(t).flatten() }
67
68 #[inline]
69 fn and_if<F: FnOnce() -> Self>(self, f: F) -> Self { self.and_is(f()) }
70
71 #[inline]
72 fn and_is(self, b: Self) -> Self { self && b }
73
74 #[inline]
75 fn and_then<T, F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> { self.then(f).flatten() }
76
77 #[inline]
78 fn clone_or<T: Clone>(self, err: T, t: &T) -> T { self.map_or(err, || t.clone()) }
79
80 #[inline]
81 fn copy_or<T: Copy>(self, err: T, t: T) -> T { self.map_or(err, || t) }
82
83 #[inline]
84 fn expect(self, msg: &str) -> Self { self.then_some(true).expect(msg) }
85
86 #[inline]
87 fn expect_false(self, msg: &str) -> Self { self.is_false().then_some(false).expect(msg) }
88
89 #[inline]
90 fn into_option(self) -> Option<()> { self.then_some(()) }
91
92 #[inline]
93 fn into_result(self) -> Result<(), ()> { self.ok_or(()) }
94
95 #[inline]
96 fn is_false(&self) -> Self { self.eq(&false) }
97
98 #[inline]
99 fn map<T, F: FnOnce(Self) -> T>(self, f: F) -> T
100 where
101 Self: Sized,
102 {
103 f(self)
104 }
105
106 #[inline]
107 fn map_ok_or<T, E, F: FnOnce() -> T>(self, err: E, f: F) -> Result<T, E> {
108 self.ok_or(err).map(|()| f())
109 }
110
111 #[inline]
112 fn map_or<T, F: FnOnce() -> T>(self, err: T, f: F) -> T { self.then(f).unwrap_or(err) }
113
114 #[inline]
115 fn map_or_else<T, E: FnOnce() -> T, F: FnOnce() -> T>(self, err: E, f: F) -> T {
116 self.then(f).unwrap_or_else(err)
117 }
118
119 #[inline]
120 fn ok_or<E>(self, err: E) -> Result<(), E> { self.into_option().ok_or(err) }
121
122 #[inline]
123 fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<(), E> {
124 self.into_option().ok_or_else(err)
125 }
126
127 #[inline]
128 fn or<T, F: FnOnce() -> T>(self, f: F) -> Option<T> { self.is_false().then(f) }
129
130 #[inline]
131 fn or_some<T>(self, t: T) -> Option<T> { self.is_false().then_some(t) }
132
133 #[inline]
134 fn then_async<O: Future, F: FnOnce() -> O>(self, f: F) -> OptionFuture<O> {
135 OptionFuture::<_>::from(self.then(f))
136 }
137
138 #[inline]
139 fn then_none<T>(self) -> Option<T> { Option::<T>::None }
140
141 #[inline]
142 fn then_ok_or<T, E>(self, t: T, e: E) -> Result<T, E> { self.map_ok_or(e, move || t) }
143
144 #[inline]
145 fn then_ok_or_else<T, E, F: FnOnce() -> E>(self, t: T, e: F) -> Result<T, E> {
146 self.ok_or_else(e).map(move |()| t)
147 }
148}