brainfoamkit_lib/
bit.rs

1// SPDX-FileCopyrightText: 2023 - 2024 Ali Sajid Imami
2//
3// SPDX-License-Identifier: Apache-2.0
4// SPDX-License-Identifier: MIT
5
6use std::{
7    fmt::{
8        self,
9        Display,
10        Formatter,
11    },
12    ops::{
13        BitAnd,
14        BitAndAssign,
15        BitOr,
16        BitOrAssign,
17        BitXor,
18        BitXorAssign,
19        Not,
20    },
21};
22
23/// Representation of a single bit.
24///
25/// This Enum is the most basic building block of the `BrainfoamKit` library.
26/// This encodes a single bit, which can be either a 0 or a 1.
27/// I have implemented this as an Enum to ensure that the only possible values
28/// are 0 and 1. Additionally, the variants are not public and can only be
29/// accessed through the `Bit::zero()` and `Bit::one()` constructor functions.
30///
31/// # Examples
32///
33/// ## Create with helper functions
34///
35/// ```
36/// use brainfoamkit_lib::Bit;
37///
38/// let bit = Bit::zero();
39/// assert_eq!(bit, Bit::Zero);
40/// let bit = Bit::one();
41/// assert_eq!(bit, Bit::One);
42/// ```
43/// ## Perform basic operations
44///
45/// ```
46/// use brainfoamkit_lib::Bit;
47///
48/// let mut bit = Bit::zero();
49/// bit.flip();
50/// assert_eq!(bit, Bit::One);
51/// let mut bit = Bit::one();
52/// bit.flip();
53/// assert_eq!(bit, Bit::Zero);
54/// ```
55///
56/// ## Display the value
57///
58/// ```
59/// use brainfoamkit_lib::Bit;
60///
61/// let bit = Bit::zero();
62/// assert_eq!(format!("{}", bit), "0");
63/// let bit = Bit::one();
64/// assert_eq!(format!("{}", bit), "1");
65/// ```
66///
67/// ## Convert to a u8
68///
69/// ```
70/// use brainfoamkit_lib::Bit;
71///
72/// let bit = Bit::zero();
73/// assert_eq!(u8::from(bit), 0);
74/// let bit = Bit::one();
75/// assert_eq!(u8::from(bit), 1);
76/// ```
77///
78/// ## Perform logical operations
79///
80/// ```
81/// use brainfoamkit_lib::Bit;
82///
83/// let bit = Bit::zero() & Bit::zero();
84/// assert_eq!(bit, Bit::Zero);
85/// let bit = Bit::zero() | Bit::one();
86/// assert_eq!(bit, Bit::One);
87/// let bit = Bit::one() ^ Bit::one();
88/// assert_eq!(bit, Bit::Zero);
89/// ```
90///
91/// # See Also
92///
93/// * [`Nybble`](crate::Nybble): A 4-bit value composed of 4 Bits.
94/// * [`Byte`](crate::Byte): An 8-bit value composed of 8 Bits.
95#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
96pub enum Bit {
97    /// The zero variant of the Bit Enum.
98    /// Represents the value 0 or the Off state.
99    Zero,
100    /// The one variant of the Bit Enum.
101    /// Represents the value 1 or the On state.
102    One,
103}
104
105impl Bit {
106    /// Constructs a new Bit with the value 0.
107    ///
108    /// This function returns a value of the `Bit` Enum with the `Bit::Zero`
109    /// variant.
110    ///
111    /// # Examples
112    ///
113    /// ```
114    /// use brainfoamkit_lib::Bit;
115    ///
116    /// let bit = Bit::zero();
117    /// assert_eq!(bit, Bit::Zero);
118    /// assert_eq!(bit.to_string(), "0");
119    /// ```
120    ///
121    /// # Returns
122    ///
123    /// A new Bit with the `Bit::Zero` variant.
124    ///
125    /// # See Also
126    ///
127    /// * [`Bit::one()`](#method.one): Constructs a new Bit with the value 1.
128    #[must_use]
129    pub const fn zero() -> Self {
130        Self::Zero
131    }
132
133    /// Constructs a new Bit with the value 1.
134    ///
135    /// This function returns a value of the `Bit` Enum with the `Bit::One`
136    /// variant.
137    ///
138    /// # Examples
139    ///
140    /// ```
141    /// use brainfoamkit_lib::Bit;
142    ///
143    /// let bit = Bit::one();
144    /// assert_eq!(bit, Bit::One);
145    /// assert_eq!(bit.to_string(), "1");
146    /// ```
147    /// # Returns
148    ///
149    /// A new Bit with the `Bit::One` variant.
150    ///
151    /// # See Also
152    ///
153    /// * [`Bit::zero()`](#method.zero): Constructs a new Bit with the value 0.
154    #[must_use]
155    pub const fn one() -> Self {
156        Self::One
157    }
158
159    /// Flips the value of the Bit.
160    ///
161    /// This function flips the value of the Bit.
162    /// This means that if the Bit is `Bit::Zero` it will become `Bit::One` and
163    /// vice versa.
164    ///
165    /// # Examples
166    ///
167    /// ```
168    /// use brainfoamkit_lib::Bit;
169    ///
170    /// let mut bit = Bit::zero();
171    /// bit.flip();
172    /// assert_eq!(bit, Bit::One);
173    /// let mut bit = Bit::one();
174    /// bit.flip();
175    /// assert_eq!(bit, Bit::Zero);
176    /// ```
177    ///
178    /// # Side Effects
179    ///
180    /// The value of the Bit is flipped.
181    ///
182    /// # See Also
183    ///
184    /// * [`Bit::set()`](#method.set): Sets the value of the Bit to 1.
185    /// * [`Bit::unset()`](#method.unset): Sets the value of the Bit to 0.
186    /// * [`Bit::is_set()`](#method.is_set): Checks if the value of the Bit is
187    ///   1.
188    /// * [`Bit::is_unset()`](#method.is_unset): Checks if the value of the Bit
189    ///   is 0.
190    pub fn flip(&mut self) {
191        *self = match self {
192            Self::Zero => Self::One,
193            Self::One => Self::Zero,
194        }
195    }
196
197    /// Set the bit
198    ///
199    /// This function *sets* the bit.
200    /// This means that the value of the bit is set to 1.
201    /// This function ignores the current value of the bit.
202    ///
203    /// # Examples
204    ///
205    /// ```
206    /// use brainfoamkit_lib::Bit;
207    ///
208    /// let mut bit = Bit::zero();
209    /// bit.set();
210    /// assert_eq!(bit, Bit::One);
211    /// ```
212    ///
213    /// # Side Effects
214    ///
215    /// The value of the Bit is set to 1.
216    ///
217    /// # Notes
218    ///
219    /// This is equivalent to calling `bit.flip()` on a `Bit::Zero`.
220    ///
221    /// # See Also
222    ///
223    /// * [`Bit::flip()`](#method.flip): Flips the value of the Bit.
224    /// * [`Bit::unset()`](#method.unset): Sets the value of the Bit to 0.
225    /// * [`Bit::is_set()`](#method.is_set): Checks if the value of the Bit is
226    ///   1.
227    /// * [`Bit::is_unset()`](#method.is_unset): Checks if the value of the Bit
228    ///   is 0.
229    pub fn set(&mut self) {
230        *self = Self::One;
231    }
232
233    /// Unset the bit
234    ///
235    /// This function unsets the bit.
236    /// This means that the value of the bit is set to 0.
237    /// This function ignores the current value of the bit.
238    ///
239    /// # Examples
240    ///
241    /// ```
242    /// use brainfoamkit_lib::Bit;
243    ///
244    /// let mut bit = Bit::one();
245    /// bit.unset();
246    /// assert_eq!(bit, Bit::Zero);
247    /// ```
248    ///
249    /// # Side Effects
250    ///
251    /// The value of the Bit is set to 0.
252    ///
253    /// # Notes
254    ///
255    /// This is equivalent to calling `bit.flip()` on a `Bit::One`.
256    ///
257    /// # See Also
258    ///
259    /// * [`Bit::flip()`](#method.flip): Flips the value of the Bit.
260    /// * [`Bit::set()`](#method.set): Sets the value of the Bit to 1.
261    /// * [`Bit::is_set()`](#method.is_set): Checks if the value of the Bit is
262    ///   1.
263    /// * [`Bit::is_unset()`](#method.is_unset): Checks if the value of the Bit
264    ///   is 0.
265    pub fn unset(&mut self) {
266        *self = Self::Zero;
267    }
268
269    /// Check if the bit is set
270    ///
271    /// This function checks if the bit is set (i.e. has the value of
272    /// `Bit::One`).
273    ///
274    /// # Examples
275    ///
276    /// ```
277    /// use brainfoamkit_lib::Bit;
278    ///
279    /// let bit = Bit::one();
280    /// assert!(bit.is_set());
281    /// ```
282    ///
283    /// # Returns
284    ///
285    /// A boolean indicating if the bit is set.
286    ///
287    /// # See Also
288    ///
289    /// * [`Bit::is_unset()`](#method.is_unset): Checks if the bit is unset.
290    /// * [`Bit::set()`](#method.set): Sets the value of the Bit to 1.
291    /// * [`Bit::unset()`](#method.unset): Sets the value of the Bit to 0.
292    #[must_use]
293    pub fn is_set(&self) -> bool {
294        *self == Self::One
295    }
296
297    /// Check if the bit is unset
298    ///
299    /// This function checks if the bit is unset (i.e. has the value of
300    /// `Bit::Zero`).
301    ///
302    /// # Examples
303    ///
304    /// ```
305    /// use brainfoamkit_lib::Bit;
306    ///
307    /// let bit = Bit::zero();
308    /// assert!(bit.is_unset());
309    /// ```
310    ///
311    /// # Returns
312    ///
313    /// A boolean indicating if the bit is unset.
314    ///
315    /// # See Also
316    ///
317    /// * [`Bit::is_set()`](#method.is_set): Checks if the bit is set.
318    /// * [`Bit::set()`](#method.set): Sets the value of the Bit to 1.
319    /// * [`Bit::unset()`](#method.unset): Sets the value of the Bit to 0.
320    #[must_use]
321    pub fn is_unset(&self) -> bool {
322        *self == Self::Zero
323    }
324}
325
326impl Display for Bit {
327    /// Display the value of the Bit.
328    ///
329    /// This function displays the value of the Bit.
330    ///
331    /// # Examples
332    ///
333    /// ```
334    /// use brainfoamkit_lib::Bit;
335    ///
336    /// let bit = Bit::zero();
337    /// assert_eq!(format!("{}", bit), "0");
338    ///
339    /// let bit = Bit::one();
340    /// assert_eq!(format!("{}", bit), "1");
341    /// ```
342    ///
343    /// # Returns
344    ///
345    /// A string containing the value of the Bit.
346    ///
347    /// # See Also
348    ///
349    /// * [`Bit::to_string()`](#method.to_string): Converts the Bit to a string.
350    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
351        match self {
352            Self::Zero => write!(f, "0"),
353            Self::One => write!(f, "1"),
354        }
355    }
356}
357
358impl Default for Bit {
359    /// Create a new Bit with the value 0.
360    ///
361    /// This function returns a new Bit with the value 0.
362    ///
363    /// # Examples
364    ///
365    /// ```
366    /// use brainfoamkit_lib::Bit;
367    ///
368    /// let bit = Bit::default();
369    /// assert_eq!(bit, Bit::Zero);
370    /// ```
371    ///
372    /// # Returns
373    ///
374    /// A new Bit with the value 0.
375    ///
376    /// # See Also
377    ///
378    /// * [`Bit::zero()`](#method.zero): Constructs a new Bit with the value 0.
379    /// * [`Bit::one()`](#method.one): Constructs a new Bit with the value 1.
380    fn default() -> Self {
381        Self::zero()
382    }
383}
384
385impl From<u8> for Bit {
386    /// Create a new Bit from a u8.
387    ///
388    /// This function returns a new Bit with the value of the u8.
389    ///
390    /// # Arguments
391    ///
392    /// * `value` - The value to create the Bit from.
393    ///
394    /// # Examples
395    ///
396    /// ```
397    /// use brainfoamkit_lib::Bit;
398    ///
399    /// let bit = Bit::from(0);
400    /// assert_eq!(bit, Bit::Zero);
401    ///
402    /// let bit = Bit::from(1);
403    /// assert_eq!(bit, Bit::One);
404    /// ```
405    ///
406    /// # Returns
407    ///
408    /// A new Bit with the value of the u8.
409    ///
410    /// # See Also
411    ///
412    /// * [`Bit::zero()`](#method.zero): Constructs a new Bit with the value 0.
413    /// * [`Bit::one()`](#method.one): Constructs a new Bit with the value 1.
414    fn from(value: u8) -> Self {
415        match value {
416            0 => Self::Zero,
417            _ => Self::One,
418        }
419    }
420}
421
422impl From<Bit> for u8 {
423    /// Convert a Bit to a u8.
424    ///
425    /// This function returns the value of the Bit as a u8.
426    ///
427    /// # Arguments
428    ///
429    /// * `bit` - The Bit to convert to a u8.
430    ///
431    /// # Examples
432    ///
433    /// ```
434    /// use brainfoamkit_lib::Bit;
435    ///
436    /// let bit = Bit::zero();
437    /// assert_eq!(u8::from(bit), 0);
438    ///
439    /// let bit = Bit::one();
440    /// assert_eq!(u8::from(bit), 1);
441    /// ```
442    ///
443    /// # Returns
444    ///
445    /// The value of the Bit as a u8.
446    ///
447    /// # See Also
448    ///
449    /// * [`Bit::to_u8()`](#method.to_u8): Converts the Bit to a u8.
450    fn from(bit: Bit) -> Self {
451        match bit {
452            Bit::Zero => 0,
453            Bit::One => 1,
454        }
455    }
456}
457
458impl Not for Bit {
459    // The return type of the `not` function is Bit since the only possible values
460    // are 0 and 1.
461    type Output = Self;
462
463    /// Perform a logical NOT on the Bit.
464    ///
465    /// This function performs a logical NOT on the Bit.
466    /// This means that if the Bit is `Bit::Zero` it will become `Bit::One` and
467    /// vice versa. This function also allows you to use the `!` operator on
468    /// the Bit.
469    ///
470    /// # Examples
471    ///
472    /// ```
473    /// use brainfoamkit_lib::Bit;
474    ///
475    /// let bit = !Bit::zero();
476    /// assert_eq!(bit, Bit::One);
477    ///
478    /// let bit = !Bit::one();
479    /// assert_eq!(bit, Bit::Zero);
480    /// ```
481    ///
482    /// # Returns
483    ///
484    /// A new Bit with the value of the logical NOT of the Bit.
485    ///
486    /// # See Also
487    ///
488    /// * [`Bit::flip()`](#method.flip): Flips the value of the Bit.
489    /// * [`Bit::set()`](#method.set): Sets the value of the Bit to 1.
490    /// * [`Bit::unset()`](#method.unset): Sets the value of the Bit to 0.
491    /// * [`Bit::bitand()`](#method.bitand): Performs a logical AND on the Bit.
492    /// * [`Bit::bitor()`](#method.bitor): Performs a logical OR on the Bit.
493    /// * [`Bit::bitxor()`](#method.bitxor): Performs a logical XOR on the Bit.
494    /// * [`Bit::bitandassign()`](#method.bitandassign): Performs a logical AND
495    ///   on the Bit and assigns the result to the Bit.
496    /// * [`Bit::bitorassign()`](#method.bitorassign): Performs a logical OR on
497    ///   the Bit and assigns the result to the Bit.
498    /// * [`Bit::bitxorassign()`](#method.bitxorassign): Performs a logical XOR
499    ///   on the Bit and assigns the result to the Bit.
500    fn not(self) -> Self::Output {
501        match self {
502            Self::Zero => Self::One,
503            Self::One => Self::Zero,
504        }
505    }
506}
507
508impl BitOr for Bit {
509    // The return type of the `bitor` function is a Bit since the `Or` operation is
510    // symmetric.
511    type Output = Self;
512
513    /// Perform a logical OR on the Bit.
514    ///
515    /// This function performs a logical OR on the Bit.
516    /// This means that if either of the Bits is `Bit::One` the result will be
517    /// `Bit::One`, otherwise the result will be `Bit::Zero`. This function
518    /// also allows you to use the `|` operator on the Bit.
519    ///
520    /// # Arguments
521    ///
522    /// * `rhs` - The other Bit to perform the logical OR with.
523    ///
524    /// # Examples
525    ///
526    /// ```
527    /// use brainfoamkit_lib::Bit;
528    ///
529    /// let bit = Bit::zero() | Bit::zero();
530    /// assert_eq!(bit, Bit::Zero);
531    ///
532    /// let bit = Bit::zero() | Bit::one();
533    /// assert_eq!(bit, Bit::One);
534    ///
535    /// let bit = Bit::one() | Bit::zero();
536    /// assert_eq!(bit, Bit::One);
537    ///
538    /// let bit = Bit::one() | Bit::one();
539    /// assert_eq!(bit, Bit::One);
540    /// ```
541    ///
542    /// # Returns
543    ///
544    /// A new Bit with the value of the logical OR of the two Bits.
545    ///
546    /// # See Also
547    ///
548    /// * [`Bit::not()`](#method.not): Performs a logical NOT on the Bit.
549    /// * [`Bit::bitand()`](#method.bitand): Performs a logical AND on the Bit.
550    /// * [`Bit::bitxor()`](#method.bitxor): Performs a logical XOR on the Bit.
551    /// * [`Bit::bitandassign()`](#method.bitandassign): Performs a logical AND
552    ///   on the Bit and assigns the result to the Bit.
553    /// * [`Bit::bitorassign()`](#method.bitorassign): Performs a logical OR on
554    ///   the Bit and assigns the result to the Bit.
555    /// * [`Bit::bitxorassign()`](#method.bitxorassign): Performs a logical XOR
556    ///   on the Bit and assigns the result to the Bit.
557    fn bitor(self, rhs: Self) -> Self::Output {
558        match (self, rhs) {
559            (Self::Zero, Self::Zero) => Self::Zero,
560            _ => Self::One,
561        }
562    }
563}
564
565impl BitOrAssign for Bit {
566    /// Perform a logical OR on the Bit and assign the result to the Bit.
567    ///
568    /// This function performs a logical OR on the Bit and assigns the result to
569    /// the Bit. This also allows you to use the `|=` operator on the Bit.
570    ///
571    /// # Arguments
572    ///
573    /// * `rhs` - The other Bit to perform the logical OR with.
574    ///
575    /// # Examples
576    ///
577    /// ```
578    /// use brainfoamkit_lib::Bit;
579    ///
580    /// let mut bit = Bit::zero();
581    ///
582    /// bit |= Bit::zero();
583    /// assert_eq!(bit, Bit::Zero);
584    ///
585    /// bit |= Bit::one();
586    /// assert_eq!(bit, Bit::One);
587    ///
588    /// bit |= Bit::zero();
589    ///
590    /// assert_eq!(bit, Bit::One);
591    /// ```
592    ///
593    /// # Side Effects
594    ///
595    /// The value of the Bit is updated to the result of the logical OR.
596    ///
597    /// # See Also
598    ///
599    /// * [`Bit::not()`](#method.not): Performs a logical NOT on the Bit.
600    /// * [`Bit::bitand()`](#method.bitand): Performs a logical AND on the Bit.
601    /// * [`Bit::bitxor()`](#method.bitxor): Performs a logical XOR on the Bit.
602    /// * [`Bit::bitandassign()`](#method.bitandassign): Performs a logical AND
603    ///   on the Bit and assigns the result to the Bit.
604    /// * [`Bit::bitorassign()`](#method.bitorassign): Performs a logical OR on
605    ///   the Bit and assigns the result to the Bit.
606    /// * [`Bit::bitxorassign()`](#method.bitxorassign): Performs a logical XOR
607    ///   on the Bit and assigns the result to the Bit.
608    fn bitor_assign(&mut self, rhs: Self) {
609        *self = *self | rhs;
610    }
611}
612
613impl BitAnd for Bit {
614    // The return type of the `bitand` function is a Bit since the `And` operation
615    // is symmetric.
616    type Output = Self;
617
618    /// Perform a logical AND on the Bit.
619    ///
620    /// This function performs a logical AND on the Bit.
621    /// This means that if both of the Bits are `Bit::One` the result will be
622    /// `Bit::One`, otherwise the result will be `Bit::Zero`. This function
623    /// also allows you to use the `&` operator on the Bit.
624    ///
625    /// # Arguments
626    ///
627    /// * `rhs` - The other Bit to perform the logical AND with.
628    ///
629    /// # Examples
630    ///
631    /// ```
632    /// use brainfoamkit_lib::Bit;
633    ///
634    /// let bit = Bit::zero() & Bit::zero();
635    ///
636    /// assert_eq!(bit, Bit::Zero);
637    ///
638    /// let bit = Bit::zero() & Bit::one();
639    ///
640    /// assert_eq!(bit, Bit::Zero);
641    ///
642    /// let bit = Bit::one() & Bit::zero();
643    ///
644    /// assert_eq!(bit, Bit::Zero);
645    ///
646    /// let bit = Bit::one() & Bit::one();
647    ///
648    /// assert_eq!(bit, Bit::One);
649    /// ```
650    ///
651    /// # Returns
652    ///
653    /// A new Bit with the value of the logical AND of the two Bits.
654    ///
655    /// # See Also
656    ///
657    /// * [`Bit::not()`](#method.not): Performs a logical NOT on the Bit.
658    /// * [`Bit::bitor()`](#method.bitor): Performs a logical OR on the Bit.
659    /// * [`Bit::bitxor()`](#method.bitxor): Performs a logical XOR on the Bit.
660    /// * [`Bit::bitandassign()`](#method.bitandassign): Performs a logical AND
661    ///   on the Bit and assigns the result to the Bit.
662    /// * [`Bit::bitorassign()`](#method.bitorassign): Performs a logical OR on
663    ///   the Bit and assigns the result to the Bit.
664    /// * [`Bit::bitxorassign()`](#method.bitxorassign): Performs a logical XOR
665    ///   on the Bit and assigns the result to the Bit.
666    fn bitand(self, rhs: Self) -> Self::Output {
667        match (self, rhs) {
668            (Self::One, Self::One) => Self::One,
669            _ => Self::Zero,
670        }
671    }
672}
673
674impl BitAndAssign for Bit {
675    /// Perform a logical AND on the Bit and assign the result to the Bit.
676    ///
677    /// This function performs a logical AND on the Bit and assigns the result
678    /// to the Bit. This also allows you to use the `&=` operator on the
679    /// Bit.
680    ///
681    /// # Arguments
682    ///
683    /// * `rhs` - The other Bit to perform the logical AND with.
684    ///
685    /// # Examples
686    ///
687    /// ```
688    /// use brainfoamkit_lib::Bit;
689    ///
690    /// let mut bit = Bit::zero();
691    ///
692    /// bit &= Bit::zero();
693    /// assert_eq!(bit, Bit::Zero);
694    /// ```
695    ///
696    /// # Side Effects
697    ///
698    /// The value of the Bit is updated to the result of the logical AND.
699    ///
700    /// # See Also
701    ///
702    /// * [`Bit::not()`](#method.not): Performs a logical NOT on the Bit.
703    /// * [`Bit::bitor()`](#method.bitor): Performs a logical OR on the Bit.
704    /// * [`Bit::bitxor()`](#method.bitxor): Performs a logical XOR on the Bit.
705    /// * [`Bit::bitandassign()`](#method.bitandassign): Performs a logical AND
706    ///   on the Bit and assigns the result to the Bit.
707    /// * [`Bit::bitorassign()`](#method.bitorassign): Performs a logical OR on
708    ///   the Bit and assigns the result to the Bit.
709    /// * [`Bit::bitxorassign()`](#method.bitxorassign): Performs a logical XOR
710    ///   on the Bit and assigns the result to the Bit.
711    fn bitand_assign(&mut self, rhs: Self) {
712        *self = *self & rhs;
713    }
714}
715
716impl BitXor for Bit {
717    // The return type of the `bitxor` function is a Bit since the `Xor` operation
718    // is symmetric.
719    type Output = Self;
720
721    /// Perform a logical XOR on the Bit.
722    ///
723    /// This function performs a logical XOR on the Bit.
724    /// This means that if the Bits are different the result will be `Bit::One`,
725    /// otherwise the result will be `Bit::Zero`. This function also allows
726    /// you to use the `^` operator on the Bit.
727    ///
728    /// # Arguments
729    ///
730    /// * `rhs` - The other Bit to perform the logical XOR with.
731    ///
732    /// # Examples
733    ///
734    /// ```
735    /// use brainfoamkit_lib::Bit;
736    ///
737    /// let bit = Bit::zero() ^ Bit::zero();
738    ///
739    /// assert_eq!(bit, Bit::Zero);
740    ///
741    /// let bit = Bit::zero() ^ Bit::one();
742    ///
743    /// assert_eq!(bit, Bit::One);
744    /// ```
745    ///
746    /// # Returns
747    ///
748    /// A new Bit with the value of the logical XOR of the two Bits.
749    ///
750    /// # See Also
751    ///
752    /// * [`Bit::not()`](#method.not): Performs a logical NOT on the Bit.
753    /// * [`Bit::bitor()`](#method.bitor): Performs a logical OR on the Bit.
754    /// * [`Bit::bitand()`](#method.bitand): Performs a logical AND on the Bit.
755    /// * [`Bit::bitandassign()`](#method.bitandassign): Performs a logical AND
756    ///   on the Bit and assigns the result to the Bit.
757    /// * [`Bit::bitorassign()`](#method.bitorassign): Performs a logical OR on
758    ///   the Bit and assigns the result to the Bit.
759    /// * [`Bit::bitxorassign()`](#method.bitxorassign): Performs a logical XOR
760    ///   on the Bit and assigns the result to the Bit.
761    fn bitxor(self, rhs: Self) -> Self::Output {
762        match (self, rhs) {
763            (Self::Zero, Self::One) | (Self::One, Self::Zero) => Self::One,
764            _ => Self::Zero,
765        }
766    }
767}
768
769impl BitXorAssign for Bit {
770    /// Perform a logical XOR on the Bit and assign the result to the Bit.
771    ///
772    /// This function performs a logical XOR on the Bit and assigns the result
773    /// to the Bit. This also allows you to use the `^=` operator on the
774    /// Bit.
775    ///
776    /// # Arguments
777    ///
778    /// * `rhs` - The other Bit to perform the logical XOR with.
779    ///
780    /// # Examples
781    ///
782    /// ```
783    /// use brainfoamkit_lib::Bit;
784    ///
785    /// let mut bit = Bit::zero();
786    ///
787    /// bit ^= Bit::zero();
788    ///
789    /// assert_eq!(bit, Bit::Zero);
790    ///
791    /// bit ^= Bit::one();
792    ///
793    /// assert_eq!(bit, Bit::One);
794    /// ```
795    ///
796    /// # Side Effects
797    ///
798    /// The value of the Bit is updated to the result of the logical XOR.
799    ///
800    /// # See Also
801    ///
802    /// * [`Bit::not()`](#method.not): Performs a logical NOT on the Bit.
803    /// * [`Bit::bitor()`](#method.bitor): Performs a logical OR on the Bit.
804    /// * [`Bit::bitand()`](#method.bitand): Performs a logical AND on the Bit.
805    /// * [`Bit::bitxor()`](#method.bitxor): Performs a logical XOR on the Bit.
806    /// * [`Bit::bitandassign()`](#method.bitandassign): Performs a logical AND
807    ///   on the Bit and assigns the result to the Bit.
808    /// * [`Bit::bitorassign()`](#method.bitorassign): Performs a logical OR on
809    ///   the Bit and assigns the result to the Bit.
810    fn bitxor_assign(&mut self, rhs: Self) {
811        *self = *self ^ rhs;
812    }
813}
814
815#[cfg(test)]
816mod tests {
817    use super::*;
818
819    #[test]
820    fn test_zero() {
821        let bit = Bit::zero();
822        assert_eq!(bit, Bit::Zero);
823        assert_eq!(bit.to_string(), "0");
824    }
825
826    #[test]
827    fn test_one() {
828        let bit = Bit::one();
829        assert_eq!(bit, Bit::One);
830        assert_eq!(bit.to_string(), "1");
831    }
832
833    #[test]
834    fn test_flip_zero() {
835        let mut bit = Bit::zero();
836        bit.flip();
837        assert_eq!(bit, Bit::One);
838    }
839
840    #[test]
841    fn test_flip_one() {
842        let mut bit = Bit::one();
843        bit.flip();
844        assert_eq!(bit, Bit::Zero);
845    }
846
847    #[test]
848    fn test_set_zero() {
849        let mut bit = Bit::zero();
850        bit.set();
851        assert_eq!(bit, Bit::One);
852    }
853
854    #[test]
855    fn test_set_one() {
856        let mut bit = Bit::one();
857        bit.set();
858        assert_eq!(bit, Bit::One);
859    }
860
861    #[test]
862    fn test_unset_zero() {
863        let mut bit = Bit::zero();
864        bit.unset();
865        assert_eq!(bit, Bit::Zero);
866    }
867
868    #[test]
869    fn test_unset_one() {
870        let mut bit = Bit::one();
871        bit.unset();
872        assert_eq!(bit, Bit::Zero);
873    }
874
875    #[test]
876    fn test_to_u8_zero() {
877        let bit = Bit::zero();
878        assert_eq!(u8::from(bit), 0);
879    }
880
881    #[test]
882    fn test_to_u8_one() {
883        let bit = Bit::one();
884        assert_eq!(u8::from(bit), 1);
885    }
886
887    #[test]
888    fn test_display_zero() {
889        let bit = Bit::zero();
890        assert_eq!(format!("{}", bit), "0");
891    }
892
893    #[test]
894    fn test_display_one() {
895        let bit = Bit::one();
896        assert_eq!(format!("{}", bit), "1");
897    }
898
899    #[test]
900    fn test_default() {
901        let bit = Bit::default();
902        assert_eq!(bit, Bit::Zero);
903    }
904
905    #[test]
906    fn test_not_zero() {
907        let bit = !Bit::zero();
908        assert_eq!(bit, Bit::One);
909    }
910
911    #[test]
912    fn test_not_one() {
913        let bit = !Bit::one();
914        assert_eq!(bit, Bit::Zero);
915    }
916
917    #[test]
918    fn test_bitor_zero_zero() {
919        let bit = Bit::zero() | Bit::zero();
920        assert_eq!(bit, Bit::Zero);
921    }
922
923    #[test]
924    fn test_bitor_zero_one() {
925        let bit = Bit::zero() | Bit::one();
926        assert_eq!(bit, Bit::One);
927    }
928
929    #[test]
930    fn test_bitor_one_zero() {
931        let bit = Bit::one() | Bit::zero();
932        assert_eq!(bit, Bit::One);
933    }
934
935    #[test]
936    fn test_bitor_one_one() {
937        let bit = Bit::one() | Bit::one();
938        assert_eq!(bit, Bit::One);
939    }
940
941    #[test]
942    fn test_bitorassign_zero_zero() {
943        let mut bit = Bit::zero();
944        bit |= Bit::zero();
945        assert_eq!(bit, Bit::Zero);
946    }
947
948    #[test]
949    fn test_bitorassign_zero_one() {
950        let mut bit = Bit::zero();
951        bit |= Bit::one();
952        assert_eq!(bit, Bit::One);
953    }
954
955    #[test]
956    fn test_bitorassign_one_zero() {
957        let mut bit = Bit::one();
958        bit |= Bit::zero();
959        assert_eq!(bit, Bit::One);
960    }
961
962    #[test]
963    fn test_bitorassign_one_one() {
964        let mut bit = Bit::one();
965        bit |= Bit::one();
966        assert_eq!(bit, Bit::One);
967    }
968
969    #[test]
970    fn test_bitand_zero_zero() {
971        let bit = Bit::zero() & Bit::zero();
972        assert_eq!(bit, Bit::Zero);
973    }
974
975    #[test]
976    fn test_bitand_zero_one() {
977        let bit = Bit::zero() & Bit::one();
978        assert_eq!(bit, Bit::Zero);
979    }
980
981    #[test]
982    fn test_bitand_one_zero() {
983        let bit = Bit::one() & Bit::zero();
984        assert_eq!(bit, Bit::Zero);
985    }
986
987    #[test]
988    fn test_bitand_one_one() {
989        let bit = Bit::one() & Bit::one();
990        assert_eq!(bit, Bit::One);
991    }
992
993    #[test]
994    fn test_bitandassign_zero_zero() {
995        let mut bit = Bit::zero();
996        bit &= Bit::zero();
997        assert_eq!(bit, Bit::Zero);
998    }
999
1000    #[test]
1001    fn test_bitandassign_zero_one() {
1002        let mut bit = Bit::zero();
1003        bit &= Bit::one();
1004        assert_eq!(bit, Bit::Zero);
1005    }
1006
1007    #[test]
1008    fn test_bitandassign_one_zero() {
1009        let mut bit = Bit::one();
1010        bit &= Bit::zero();
1011        assert_eq!(bit, Bit::Zero);
1012    }
1013
1014    #[test]
1015    fn test_bitandassign_one_one() {
1016        let mut bit = Bit::one();
1017        bit &= Bit::one();
1018        assert_eq!(bit, Bit::One);
1019    }
1020
1021    #[test]
1022    fn test_bitxor_zero_zero() {
1023        let bit = Bit::zero() ^ Bit::zero();
1024        assert_eq!(bit, Bit::Zero);
1025    }
1026
1027    #[test]
1028    fn test_bitxor_zero_one() {
1029        let bit = Bit::zero() ^ Bit::one();
1030        assert_eq!(bit, Bit::One);
1031    }
1032
1033    #[test]
1034    fn test_bitxor_one_zero() {
1035        let bit = Bit::one() ^ Bit::zero();
1036        assert_eq!(bit, Bit::One);
1037    }
1038
1039    #[test]
1040    fn test_bitxor_one_one() {
1041        let bit = Bit::one() ^ Bit::one();
1042        assert_eq!(bit, Bit::Zero);
1043    }
1044
1045    #[test]
1046    fn test_bitxorassign_zero_zero() {
1047        let mut bit = Bit::zero();
1048        bit ^= Bit::zero();
1049        assert_eq!(bit, Bit::Zero);
1050    }
1051
1052    #[test]
1053    fn test_bitxorassign_zero_one() {
1054        let mut bit = Bit::zero();
1055        bit ^= Bit::one();
1056        assert_eq!(bit, Bit::One);
1057    }
1058
1059    #[test]
1060    fn test_bitxorassign_one_zero() {
1061        let mut bit = Bit::one();
1062        bit ^= Bit::zero();
1063        assert_eq!(bit, Bit::One);
1064    }
1065
1066    #[test]
1067    fn test_bitxorassign_one_one() {
1068        let mut bit = Bit::one();
1069        bit ^= Bit::one();
1070        assert_eq!(bit, Bit::Zero);
1071    }
1072
1073    #[test]
1074    fn test_is_set_zero() {
1075        let bit = Bit::zero();
1076        assert!(!bit.is_set());
1077    }
1078
1079    #[test]
1080    fn test_is_set_one() {
1081        let bit = Bit::one();
1082        assert!(bit.is_set());
1083    }
1084
1085    #[test]
1086    fn test_is_unset_zero() {
1087        let bit = Bit::zero();
1088        assert!(bit.is_unset());
1089    }
1090
1091    #[test]
1092    fn test_is_unset_one() {
1093        let bit = Bit::one();
1094        assert!(!bit.is_unset());
1095    }
1096
1097    #[test]
1098    fn test_is_set_after_set() {
1099        let mut bit = Bit::zero();
1100        bit.set();
1101        assert!(bit.is_set());
1102    }
1103
1104    #[test]
1105    fn test_is_unset_after_set() {
1106        let mut bit = Bit::zero();
1107        bit.set();
1108        assert!(!bit.is_unset());
1109    }
1110
1111    #[test]
1112    fn test_is_set_after_unset() {
1113        let mut bit = Bit::one();
1114        bit.unset();
1115        assert!(!bit.is_set());
1116    }
1117
1118    #[test]
1119    fn test_is_unset_after_unset() {
1120        let mut bit = Bit::one();
1121        bit.unset();
1122        assert!(bit.is_unset());
1123    }
1124}