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