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}