#[derive(Clone)]
pub struct ByteMaskCombinator {
byte: u8,
mask: u8,
i: u8,
done: bool,
}
impl ByteMaskCombinator {
pub fn new(byte: u8, mask: u8) -> Self {
Self { byte, mask, i: 0, done: false }
}
}
impl Iterator for ByteMaskCombinator {
type Item = u8;
fn next(&mut self) -> Option<Self::Item> {
if self.done {
return None;
}
let next = (self.byte & self.mask) | (self.i & !self.mask);
(self.i, self.done) = (self.i | self.mask).overflowing_add(1);
Some(next)
}
}
#[cfg(test)]
mod tests {
use crate::compiler::atoms::mask::ByteMaskCombinator;
use pretty_assertions::assert_eq;
#[test]
fn mask_combinator() {
let mut c = ByteMaskCombinator::new(0xaa, 0xff);
assert_eq!(c.next(), Some(0xaa));
assert_eq!(c.next(), None);
let mut c = ByteMaskCombinator::new(0b1000_0000, 0b1111_1110);
assert_eq!(c.next(), Some(0b1000_0000u8));
assert_eq!(c.next(), Some(0b1000_0001u8));
assert_eq!(c.next(), None);
let mut c = ByteMaskCombinator::new(0b1101_1010, 0b1101_1010);
assert_eq!(c.next(), Some(0b1101_1010u8));
assert_eq!(c.next(), Some(0b1101_1011u8));
assert_eq!(c.next(), Some(0b1101_1110u8));
assert_eq!(c.next(), Some(0b1101_1111u8));
assert_eq!(c.next(), Some(0b1111_1010u8));
assert_eq!(c.next(), Some(0b1111_1011u8));
assert_eq!(c.next(), Some(0b1111_1110u8));
assert_eq!(c.next(), Some(0b1111_1111u8));
assert_eq!(c.next(), None);
let mut c = ByteMaskCombinator::new(0xcc, 0x00);
for i in 0..=0xff {
assert_eq!(c.next(), Some(i));
}
assert_eq!(c.next(), None);
let mut c = ByteMaskCombinator::new(0x33, 0xf0);
for i in 0x30..=0x3f {
assert_eq!(c.next(), Some(i));
}
assert_eq!(c.next(), None);
}
}