bitworks/
bit.rs

1//! Module containing [`Bit`] enum as well as [`BitRef`] and [`BitMut`] smart pointers.
2
3use crate::{bitset::Bitset, prelude::Index};
4use std::{
5    fmt::{Debug, Display},
6    ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Deref, DerefMut, Not},
7};
8
9/// Enum representing all possible states of a bit in a [`Bitset`].
10/// Variants are re-exported and don't require `Bit::` prefix.
11///
12/// Closely resembles [`bool`] type. Implements [`From<bool>`][core::convert::From],
13/// and bool implements `From<Bit>`, if such conversion is needed.
14///
15/// # Examples
16/// ```rust
17/// # use std::error::Error;
18/// #
19/// # fn main() -> Result<(), Box<dyn Error>> {
20/// use bitworks::{bit::*, prelude::{Bitset, Bitset8}};
21///
22/// assert_eq!(!One, Zero);
23/// assert_eq!(One | Zero, One);
24/// assert_eq!(One & Zero, Zero);
25/// assert_eq!(One ^ Zero, One);
26/// assert_eq!(One ^ One, Zero);
27///
28/// let bitset = Bitset8::NONE
29///     .replace(0.try_into()?, One)
30///     .build();
31///
32/// assert_eq!(bitset.into_inner(), 0b00000001);
33/// #   Ok(())
34/// # }
35/// ```
36#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
37#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
38pub enum Bit {
39    /// Also known as `unset` state of the bit.
40    Zero,
41    /// Also known as `set` state of the bit.
42    One,
43}
44
45pub use Bit::*;
46
47impl Not for Bit {
48    type Output = Self;
49
50    fn not(self) -> Self::Output {
51        match self {
52            Zero => One,
53            One => Zero,
54        }
55    }
56}
57
58impl BitAnd for Bit {
59    type Output = Self;
60
61    fn bitand(self, rhs: Self) -> Self::Output {
62        if self == One && rhs == One {
63            One
64        } else {
65            Zero
66        }
67    }
68}
69
70impl BitAndAssign for Bit {
71    fn bitand_assign(&mut self, rhs: Self) {
72        *self = if *self == One && rhs == One {
73            One
74        } else {
75            Zero
76        }
77    }
78}
79
80impl BitOr for Bit {
81    type Output = Self;
82
83    fn bitor(self, rhs: Self) -> Self::Output {
84        if self == One || rhs == One {
85            One
86        } else {
87            Zero
88        }
89    }
90}
91
92impl BitOrAssign for Bit {
93    fn bitor_assign(&mut self, rhs: Self) {
94        *self = if *self == One || rhs == One {
95            One
96        } else {
97            Zero
98        }
99    }
100}
101
102impl BitXor for Bit {
103    type Output = Self;
104
105    fn bitxor(self, rhs: Self) -> Self::Output {
106        if self != rhs {
107            One
108        } else {
109            Zero
110        }
111    }
112}
113
114impl BitXorAssign for Bit {
115    fn bitxor_assign(&mut self, rhs: Self) {
116        *self = if *self != rhs { One } else { Zero }
117    }
118}
119
120impl From<bool> for Bit {
121    #[inline(always)]
122    fn from(value: bool) -> Self {
123        match value {
124            true => One,
125            false => Zero,
126        }
127    }
128}
129
130impl From<Bit> for bool {
131    #[inline(always)]
132    fn from(value: Bit) -> Self {
133        match value {
134            Zero => false,
135            One => true,
136        }
137    }
138}
139
140impl Display for Bit {
141    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142        write!(
143            f,
144            "{}",
145            match *self {
146                Zero => 0,
147                One => 1,
148            }
149        )
150    }
151}
152
153/// Smart pointer granting immutable access to a bit in [`Bitset`].
154///
155/// Is not meant to be created manually, instead use methods defined on `Bitset`
156/// to get a value of this type.
157/// This type isn't magic, it actually holds the [`Bit`] value.
158///
159/// # Examples
160/// ```rust
161/// # use std::error::Error;
162/// #
163/// # fn main() -> Result<(), Box<dyn Error>> {
164/// use bitworks::prelude::*;
165///
166/// let bitset = Bitset8::NONE.set(1.try_into()?).build();
167///
168/// assert_eq!(*bitset.bit_ref(0.try_into()?), Zero);
169/// assert_eq!(*bitset.bit_ref(1.try_into()?), One);
170/// #   Ok(())
171/// # }
172/// ```
173#[derive(PartialEq, Eq)]
174pub struct BitRef<'a, T: Bitset + 'a>(pub(crate) Bit, pub(crate) Index<T>, pub(crate) &'a T);
175
176impl<'a, T: 'a> BitRef<'a, T>
177where
178    T: Bitset,
179    Self: 'a,
180{
181    /// Constructs a new value of `BitRef`
182    pub fn new(value: Bit, index: Index<T>, owner: &'a T) -> Self {
183        Self(value, index, owner)
184    }
185
186    /// Returns index of the bit, referenced by `BitRef`.
187    pub fn index(bit_ref: &'a Self) -> Index<T> {
188        bit_ref.1
189    }
190}
191
192impl<'a, T: 'a> Deref for BitRef<'a, T>
193where
194    T: Bitset,
195    Self: 'a,
196{
197    type Target = Bit;
198
199    fn deref(&self) -> &Self::Target {
200        &self.0
201    }
202}
203
204impl<'a, T: 'a> AsRef<Bit> for BitRef<'a, T>
205where
206    T: Bitset,
207    Self: 'a,
208{
209    fn as_ref(&self) -> &Bit {
210        &self.0
211    }
212}
213
214impl<'a, T: 'a> Clone for BitRef<'a, T>
215where
216    T: Bitset,
217    Self: 'a,
218{
219    fn clone(&self) -> Self {
220        *self
221    }
222}
223
224impl<'a, T: 'a> Copy for BitRef<'a, T> where T: Bitset {}
225
226impl<'a, T: 'a> Debug for BitRef<'a, T>
227where
228    T: Bitset,
229    Self: 'a,
230{
231    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
232        f.debug_tuple("BitRef")
233            .field(&self.0)
234            .field(&self.1)
235            .finish()
236    }
237}
238
239impl<'a, T: 'a> Display for BitRef<'a, T>
240where
241    T: Bitset,
242    Self: 'a,
243{
244    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
245        write!(
246            f,
247            "{}",
248            match self.0 {
249                Zero => 0,
250                One => 1,
251            }
252        )
253    }
254}
255
256/// Smart pointer granting mutable access to a bit in [`Bitset`].
257///
258/// Is not meant to be created manually, instead use methods defined on `Bitset`
259/// to get a value of this type.
260/// This type isn't magic, it actually holds the [`Bit`] value.
261///
262/// # Examples
263/// ```rust
264/// # use std::error::Error;
265/// #
266/// # fn main() -> Result<(), Box<dyn Error>> {
267/// use bitworks::prelude::*;
268///
269/// let mut bitset = Bitset8::NONE;
270///
271/// assert_eq!(bitset.bit(0.try_into()?), Zero);
272/// assert_eq!(bitset.bit(1.try_into()?), Zero);
273///
274/// *bitset.bit_mut(0.try_into()?) = One;
275///
276/// assert_eq!(bitset.bit(0.try_into()?), One);
277/// assert_eq!(bitset.bit(1.try_into()?), Zero);
278/// #   Ok(())
279/// # }
280/// ```
281#[derive(PartialEq, Eq)]
282pub struct BitMut<'a, T: Bitset + 'a>(pub(crate) Bit, pub(crate) Index<T>, pub(crate) &'a mut T);
283
284impl<'a, T: 'a> BitMut<'a, T>
285where
286    T: Bitset,
287    Self: 'a,
288{
289    /// Constructs a new value of `BitMut`
290    pub fn new(value: Bit, index: Index<T>, owner: &'a mut T) -> Self {
291        Self(value, index, owner)
292    }
293
294    /// Returns index of the bit, referenced by `BitMut`.
295    pub fn index(bit_mut: &'a Self) -> Index<T> {
296        bit_mut.1
297    }
298}
299
300impl<'a, T: 'a> Drop for BitMut<'a, T>
301where
302    T: Bitset,
303    Self: 'a,
304{
305    fn drop(&mut self) {
306        self.2.replace(self.1, self.0);
307    }
308}
309
310impl<'a, T: 'a> Deref for BitMut<'a, T>
311where
312    T: Bitset,
313    Self: 'a,
314{
315    type Target = Bit;
316
317    fn deref(&self) -> &Self::Target {
318        &self.0
319    }
320}
321
322impl<'a, T: 'a> DerefMut for BitMut<'a, T>
323where
324    T: Bitset,
325    Self: 'a,
326{
327    fn deref_mut(&mut self) -> &mut Self::Target {
328        &mut self.0
329    }
330}
331
332impl<'a, T: 'a> AsRef<Bit> for BitMut<'a, T>
333where
334    T: Bitset,
335    Self: 'a,
336{
337    fn as_ref(&self) -> &Bit {
338        &self.0
339    }
340}
341
342impl<'a, T: 'a> AsMut<Bit> for BitMut<'a, T>
343where
344    T: Bitset,
345    Self: 'a,
346{
347    fn as_mut(&mut self) -> &mut Bit {
348        &mut self.0
349    }
350}
351
352impl<'a, T: 'a> Debug for BitMut<'a, T>
353where
354    T: Bitset,
355    Self: 'a,
356{
357    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
358        f.debug_tuple("BitMut")
359            .field(&self.0)
360            .field(&self.1)
361            .finish()
362    }
363}
364
365impl<'a, T: 'a> Display for BitMut<'a, T>
366where
367    T: Bitset,
368    Self: 'a,
369{
370    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
371        write!(
372            f,
373            "{}",
374            match self.0 {
375                Zero => 0,
376                One => 1,
377            }
378        )
379    }
380}