Skip to main content

reflect_nat/
bool.rs

1//! Type-level booleans with [`Reflect`] implementations.
2
3use reify_reflect_core::Reflect;
4
5/// Type-level `true`.
6///
7/// # Examples
8///
9/// ```
10/// use reflect_nat::True;
11/// use reify_reflect_core::Reflect;
12///
13/// assert_eq!(True::reflect(), true);
14/// ```
15pub struct True;
16
17/// Type-level `false`.
18///
19/// # Examples
20///
21/// ```
22/// use reflect_nat::False;
23/// use reify_reflect_core::Reflect;
24///
25/// assert_eq!(False::reflect(), false);
26/// ```
27pub struct False;
28
29/// Marker trait for type-level booleans.
30///
31/// # Examples
32///
33/// ```
34/// use reflect_nat::{True, False, Bool};
35///
36/// fn require_bool<B: Bool>() -> bool { B::to_bool() }
37/// assert!(require_bool::<True>());
38/// assert!(!require_bool::<False>());
39/// ```
40pub trait Bool {
41    /// The runtime `bool` value of this type-level boolean.
42    fn to_bool() -> bool;
43}
44
45impl Bool for True {
46    fn to_bool() -> bool {
47        true
48    }
49}
50
51impl Bool for False {
52    fn to_bool() -> bool {
53        false
54    }
55}
56
57impl Reflect for True {
58    type Value = bool;
59
60    fn reflect() -> Self::Value {
61        true
62    }
63}
64
65impl Reflect for False {
66    type Value = bool;
67
68    fn reflect() -> Self::Value {
69        false
70    }
71}
72
73/// Type-level boolean NOT.
74///
75/// # Examples
76///
77/// ```
78/// use reflect_nat::{True, False, Not};
79/// use reify_reflect_core::Reflect;
80///
81/// assert_eq!(<<True as Not>::Result as Reflect>::reflect(), false);
82/// assert_eq!(<<False as Not>::Result as Reflect>::reflect(), true);
83/// ```
84pub trait Not {
85    /// The negated type-level boolean.
86    type Result: Bool;
87}
88
89impl Not for True {
90    type Result = False;
91}
92
93impl Not for False {
94    type Result = True;
95}
96
97/// Type-level boolean AND.
98///
99/// # Examples
100///
101/// ```
102/// use reflect_nat::{True, False, And, Bool};
103///
104/// assert!( <<True as And<True>>::Result as Bool>::to_bool());
105/// assert!(!<<True as And<False>>::Result as Bool>::to_bool());
106/// ```
107pub trait And<Rhs> {
108    /// The result of `Self && Rhs`.
109    type Result: Bool;
110}
111
112impl And<True> for True {
113    type Result = True;
114}
115impl And<False> for True {
116    type Result = False;
117}
118impl And<True> for False {
119    type Result = False;
120}
121impl And<False> for False {
122    type Result = False;
123}
124
125/// Type-level boolean OR.
126///
127/// # Examples
128///
129/// ```
130/// use reflect_nat::{True, False, Or, Bool};
131///
132/// assert!( <<True as Or<False>>::Result as Bool>::to_bool());
133/// assert!(!<<False as Or<False>>::Result as Bool>::to_bool());
134/// ```
135pub trait Or<Rhs> {
136    /// The result of `Self || Rhs`.
137    type Result: Bool;
138}
139
140impl Or<True> for True {
141    type Result = True;
142}
143impl Or<False> for True {
144    type Result = True;
145}
146impl Or<True> for False {
147    type Result = True;
148}
149impl Or<False> for False {
150    type Result = False;
151}
152
153#[cfg(test)]
154mod tests {
155    use super::*;
156
157    #[test]
158    fn true_reflects() {
159        assert!(True::reflect());
160    }
161
162    #[test]
163    fn false_reflects() {
164        assert!(!False::reflect());
165    }
166
167    #[test]
168    fn bool_to_bool() {
169        assert!(True::to_bool());
170        assert!(!False::to_bool());
171    }
172
173    #[test]
174    fn not() {
175        assert!(!<<True as Not>::Result as Bool>::to_bool());
176        assert!(<<False as Not>::Result as Bool>::to_bool());
177    }
178
179    #[test]
180    fn and() {
181        assert!(<<True as And<True>>::Result as Bool>::to_bool());
182        assert!(!<<True as And<False>>::Result as Bool>::to_bool());
183        assert!(!<<False as And<True>>::Result as Bool>::to_bool());
184        assert!(!<<False as And<False>>::Result as Bool>::to_bool());
185    }
186
187    #[test]
188    fn or() {
189        assert!(<<True as Or<True>>::Result as Bool>::to_bool());
190        assert!(<<True as Or<False>>::Result as Bool>::to_bool());
191        assert!(<<False as Or<True>>::Result as Bool>::to_bool());
192        assert!(!<<False as Or<False>>::Result as Bool>::to_bool());
193    }
194}