#![doc(html_root_url = "https://docs.rs/bitpat/0.1.1")]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#[macro_export]
macro_rules! bitpat {
( @build $relevant:tt $ones:tt [] ) => {
|value| value & ($relevant) == ($ones)
};
( @build $relevant:tt $ones:tt [$next:tt $($rest:tt)*] ) => {
bitpat!(@build ($relevant << 1 | bitpat!(@relevant $next)) ($ones << 1 | bitpat!(@is_one $next)) [$($rest)*])
};
( @relevant _ ) => { 0 };
( @relevant 0 ) => { 1 };
( @relevant 1 ) => { 1 };
( @is_one _ ) => { 0 };
( @is_one 0 ) => { 0 };
( @is_one 1 ) => { 1 };
( $($part:tt)+ ) => {bitpat!(@build 0 0 [$($part)+])};
}
#[cfg(test)]
mod tests {
#[test]
fn mask() {
assert!(bitpat!(0 0 _ _ 1 _ _ _)(0b00111111));
assert!(bitpat!(0 0 _ _ 1 _ _ _)(0b00001111));
assert!(bitpat!(0 0 _ _ 1 _ _ _)(0b00001000));
assert!(bitpat!(0 0 _ _ 1 _ _ _)(0b00001110));
assert!(!bitpat!(0 0 _ _ 1 _ _ _)(0b01111111));
assert!(!bitpat!(0 0 _ _ 1 _ _ _)(0b10111111));
assert!(!bitpat!(0 0 _ _ 1 _ _ _)(0b00110111));
for b in 0..255u8 {
assert_eq!(bitpat!(1 _ _ _ _ _ _ _)(b), b >= 128);
assert_eq!(bitpat!(0 _ _ _ _ _ _ _)(b), b < 128);
}
for b in 0..255u8 {
assert_eq!(bitpat!(_ _ _ _ _ _ _ 1)(b), b & 1 != 0);
assert_eq!(bitpat!(_ _ _ _ _ _ _ 0)(b), b & 1 == 0);
}
for b in 0..255u8 {
assert!(bitpat!(_ _ _ _ _ _ _ _)(b));
}
for b in 1..255u8 {
assert!(!bitpat!(0 0 0 0 0 0 0 0)(b));
}
}
#[test]
fn mask_too_short() {
assert!(bitpat!(_ _ _ _)(0b11110000));
assert!(bitpat!(_ _ _ _)(0b11111111));
assert!(bitpat!(_ _ _ _)(0b11110001));
assert!(bitpat!(_ _ _ _)(0b0000));
assert!(bitpat!(0 0 0 0)(0b11110000));
assert!(bitpat!(0 0 0 0)(0b1110000));
assert!(bitpat!(0 0 0 0)(0b110000));
assert!(bitpat!(0 0 0 0)(0b10000));
assert!(bitpat!(0 0 0 0)(0b0000));
assert!(bitpat!(1 1 1 1)(0b11111111));
assert!(bitpat!(1 1 1 1)(0b1111111));
assert!(bitpat!(1 1 1 1)(0b111111));
assert!(bitpat!(1 1 1 1)(0b11111));
assert!(bitpat!(1 1 1 1)(0b1111));
}
#[test]
fn mask_too_long() {
assert!(bitpat!(_ _ _ _ _ _ _ _ _)(0b11110000u8));
assert!(bitpat!(0 _ _ _ _ _ _ _ _)(0b11110000u8));
assert!(bitpat!(1 _ _ _ _ _ _ _ _)(0b11110000u8));
assert!(bitpat!(1 1 _ _ _ _ _ _ _)(0b11110000u8));
assert!(bitpat!(0 1 _ _ _ _ _ _ _)(0b11110000u8));
assert!(bitpat!(1 0 _ _ _ _ _ _ _)(0b01110000u8));
assert!(bitpat!(0 0 _ _ _ _ _ _ _)(0b01110000u8));
assert!(!bitpat!(1 1 _ _ _ _ _ _ _)(0b11110000));
assert!( bitpat!(0 1 _ _ _ _ _ _ _)(0b11110000));
assert!( bitpat!(_ 1 _ _ _ _ _ _ _)(0b11110000));
}
}