Skip to main content

distances/number/
_bool.rs

1//! `NumBool` is a `Number` that can be used as a boolean.
2
3use crate::Number;
4
5use super::{Addition, Multiplication};
6
7/// A `Number` that can be used as a boolean.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
9pub struct Bool(u8);
10
11impl Bool {
12    /// Creates a new `NumBool` from a `bool`.
13    #[must_use]
14    pub const fn from_bool(b: bool) -> Self {
15        Self(if b { 1 } else { 0 })
16    }
17
18    /// Returns the `NumBool` as a `bool`.
19    #[must_use]
20    pub const fn as_bool(&self) -> bool {
21        self.0 == 1
22    }
23}
24
25impl Addition for Bool {
26    const ZERO: Self = Self(0);
27}
28
29impl Multiplication for Bool {
30    const ONE: Self = Self(1);
31
32    fn mul_add(self, a: Self, b: Self) -> Self {
33        Self(self.0.mul_add(a.0, b.0))
34    }
35
36    fn mul_add_assign(&mut self, a: Self, b: Self) {
37        self.0.mul_add_assign(a.0, b.0);
38    }
39
40    fn powi(self, _: i32) -> Self {
41        if self.0 == 0 {
42            Self(0)
43        } else {
44            Self(1)
45        }
46    }
47}
48
49impl core::fmt::Display for Bool {
50    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51        write!(f, "{}", self.as_bool())
52    }
53}
54
55impl core::iter::Sum for Bool {
56    fn sum<I: Iterator<Item = Self>>(mut iter: I) -> Self {
57        if iter.any(|v| v.as_bool()) {
58            Self(1)
59        } else {
60            Self(0)
61        }
62    }
63}
64
65impl core::ops::Add for Bool {
66    type Output = Self;
67
68    fn add(self, rhs: Self) -> Self::Output {
69        Self(self.0.add(rhs.0))
70    }
71}
72
73impl core::ops::AddAssign for Bool {
74    fn add_assign(&mut self, rhs: Self) {
75        self.0.add_assign(rhs.0);
76    }
77}
78
79impl core::ops::Mul for Bool {
80    type Output = Self;
81
82    fn mul(self, rhs: Self) -> Self::Output {
83        Self(self.0.mul(rhs.0))
84    }
85}
86
87impl core::ops::MulAssign for Bool {
88    fn mul_assign(&mut self, rhs: Self) {
89        self.0.mul_assign(rhs.0);
90    }
91}
92
93impl core::ops::Rem for Bool {
94    type Output = Self;
95
96    fn rem(self, rhs: Self) -> Self::Output {
97        Self(self.0.rem(rhs.0))
98    }
99}
100
101impl core::ops::RemAssign for Bool {
102    fn rem_assign(&mut self, rhs: Self) {
103        self.0.rem_assign(rhs.0);
104    }
105}
106
107impl core::ops::Div for Bool {
108    type Output = Self;
109
110    fn div(self, rhs: Self) -> Self::Output {
111        Self(self.0.div(rhs.0))
112    }
113}
114
115impl core::ops::DivAssign for Bool {
116    fn div_assign(&mut self, rhs: Self) {
117        self.0.div_assign(rhs.0);
118    }
119}
120
121impl core::ops::Sub for Bool {
122    type Output = Self;
123
124    fn sub(self, rhs: Self) -> Self::Output {
125        Self(self.0.sub(rhs.0))
126    }
127}
128
129impl core::ops::SubAssign for Bool {
130    fn sub_assign(&mut self, rhs: Self) {
131        self.0.sub_assign(rhs.0);
132    }
133}
134
135impl core::str::FromStr for Bool {
136    type Err = String;
137
138    fn from_str(s: &str) -> Result<Self, Self::Err> {
139        let b = s.parse::<bool>().map_err(|e| e.to_string())?;
140        Ok(Self::from_bool(b))
141    }
142}
143
144impl Number for Bool {
145    const MAX: Self = Self(1);
146    const MIN: Self = Self(0);
147    const EPSILON: Self = Self(1);
148    const NUM_BYTES: usize = 1;
149
150    fn from<T: Number>(n: T) -> Self {
151        if n == T::ZERO {
152            Self::ZERO
153        } else {
154            Self::ONE
155        }
156    }
157
158    fn as_f32(self) -> f32 {
159        self.0.as_f32()
160    }
161
162    fn as_f64(self) -> f64 {
163        self.0.as_f64()
164    }
165
166    fn as_u64(self) -> u64 {
167        self.0.as_u64()
168    }
169
170    fn as_i64(self) -> i64 {
171        self.0.as_i64()
172    }
173
174    fn as_u32(self) -> u32 {
175        self.0.as_u32()
176    }
177
178    fn as_i32(self) -> i32 {
179        self.0.as_i32()
180    }
181
182    fn from_le_bytes(bytes: &[u8]) -> Self {
183        Self::from_bool(bytes[0] != 0)
184    }
185
186    fn to_le_bytes(self) -> Vec<u8> {
187        self.0.to_le_bytes().to_vec()
188    }
189
190    fn from_be_bytes(bytes: &[u8]) -> Self {
191        Self::from_le_bytes(bytes)
192    }
193
194    fn to_be_bytes(self) -> Vec<u8> {
195        self.to_le_bytes()
196    }
197
198    fn next_random<R: rand::Rng>(rng: &mut R) -> Self {
199        Self(rng.gen())
200    }
201}