brainfoamkit_lib/
iterable_byte.rs

1// SPDX-FileCopyrightText: 2023 - 2024 Ali Sajid Imami
2//
3// SPDX-License-Identifier: Apache-2.0
4// SPDX-License-Identifier: MIT
5
6use crate::{
7    Bit,
8    Byte,
9};
10
11/// An iterator over a byte
12///
13/// This struct is a wrapper struct to generate an iterator
14/// for `Byte`. This allows us to map and/or loop over all the `Bit`s
15/// in the `Byte`.
16///
17/// This iterator iterates from the Least Significant Bit (LSB) to the
18/// Most Significant Bit (MSB). This means that the first `Bit` returned
19/// is the last `Bit` in the `Byte` and the last `Bit` returned is the
20/// first `Bit` in the `Byte`.
21///
22/// # Examples
23///
24/// ```
25/// use brainfoamkit_lib::{
26///     Bit,
27///     Byte,
28///     IterableByte,
29/// };
30///
31/// let byte = Byte::from(0b1100_1010); // Dec: 10; Hex: 0xA; Oct: 0o12
32/// let mut iter = IterableByte::new(&byte);
33///
34/// assert_eq!(iter.next(), Some(Bit::zero()));
35/// assert_eq!(iter.next(), Some(Bit::one()));
36/// assert_eq!(iter.next(), Some(Bit::zero()));
37/// assert_eq!(iter.next(), Some(Bit::one()));
38/// assert_eq!(iter.next(), Some(Bit::zero()));
39/// assert_eq!(iter.next(), Some(Bit::zero()));
40/// assert_eq!(iter.next(), Some(Bit::one()));
41/// assert_eq!(iter.next(), Some(Bit::one()));
42/// assert_eq!(iter.next(), None);
43/// ```
44///
45/// # See Also
46///
47/// * [`Byte`](crate::Byte)
48/// * [`Bit`](crate::Bit)
49/// * [`Nybble`](crate::Nybble)
50/// * [`IterableNybble`](crate::IterableNybble)
51pub struct IterableByte<'a> {
52    byte:          &'a Byte,
53    current_index: u8,
54}
55
56impl<'a> IterableByte<'a> {
57    /// Create a new `IterableByte` from a reference to a `Byte`
58    ///
59    /// # Arguments
60    ///
61    /// * `byte` - A reference to a `Byte` to iterate over
62    ///
63    /// # Returns
64    ///
65    /// A new `IterableNybble` that can be used to iterate over the `Nybble`
66    ///
67    /// # Examples
68    ///
69    /// ```
70    /// use brainfoamkit_lib::{
71    ///     Byte,
72    ///     IterableByte,
73    /// };
74    ///
75    /// let byte = Byte::from(0b1100_1010); // Dec: 202; Hex: 0xCA; Oct: 0o312
76    /// let mut iter = IterableByte::new(&byte);
77    ///
78    /// for bit in iter {
79    ///     println!("{}", bit);
80    /// }
81    /// ```
82    #[must_use]
83    pub const fn new(byte: &'a Byte) -> Self {
84        Self {
85            byte,
86            current_index: 0,
87        }
88    }
89}
90
91impl<'a> Iterator for IterableByte<'a> {
92    /// The type of the element the iterator returns
93    type Item = Bit;
94
95    /// Advance the iterator and return the next element
96    ///
97    /// # Returns
98    ///
99    /// The next element in the iterator
100    ///
101    /// # Examples
102    ///
103    /// ```
104    /// use brainfoamkit_lib::{
105    ///     Bit,
106    ///     Byte,
107    ///     IterableByte,
108    /// };
109    ///
110    /// let byte = Byte::from(0b1100_1010); // Dec: 202; Hex: 0xCA; Oct: 0o312
111    ///
112    /// let mut iter = IterableByte::new(&byte);
113    ///
114    /// assert_eq!(iter.next(), Some(Bit::zero()));
115    /// assert_eq!(iter.next(), Some(Bit::one()));
116    /// assert_eq!(iter.next(), Some(Bit::zero()));
117    /// assert_eq!(iter.next(), Some(Bit::one()));
118    /// assert_eq!(iter.next(), Some(Bit::zero()));
119    /// assert_eq!(iter.next(), Some(Bit::zero()));
120    /// assert_eq!(iter.next(), Some(Bit::one()));
121    /// assert_eq!(iter.next(), Some(Bit::one()));
122    /// assert_eq!(iter.next(), None);
123    /// ```
124    fn next(&mut self) -> Option<Self::Item> {
125        let current_index = self.current_index;
126        let next_index = current_index + 1;
127
128        if next_index > 8 {
129            self.current_index = 0;
130            None
131        } else {
132            self.current_index = next_index;
133            Some(self.byte.get_bit(current_index))
134        }
135    }
136}
137
138#[cfg(test)]
139mod tests {
140    use super::*;
141
142    #[test]
143    fn test_iterable_nybble() {
144        let byte = Byte::from(0b11001010); // Dec: 10; Hex: 0xA; Oct: 0o12
145        let mut iter = byte.iter();
146
147        assert_eq!(iter.next(), Some(Bit::zero()));
148        assert_eq!(iter.next(), Some(Bit::one()));
149        assert_eq!(iter.next(), Some(Bit::zero()));
150        assert_eq!(iter.next(), Some(Bit::one()));
151        assert_eq!(iter.next(), Some(Bit::zero()));
152        assert_eq!(iter.next(), Some(Bit::zero()));
153        assert_eq!(iter.next(), Some(Bit::one()));
154        assert_eq!(iter.next(), Some(Bit::one()));
155        assert_eq!(iter.next(), None);
156    }
157}