7 releases

0.3.0 Nov 22, 2024
0.2.1 Mar 10, 2023
0.1.4 Aug 3, 2021
0.1.0 Jul 31, 2021

#811 in Rust patterns

Download history 15/week @ 2024-09-23 1/week @ 2024-09-30 1/week @ 2024-11-04 134/week @ 2024-11-18 16/week @ 2024-11-25 5/week @ 2024-12-09

155 downloads per month

MIT license

24KB
563 lines

crates-io docs-rs github

This crate provides BitBag, a type intended for tracking bitflags defined in a field-less enum. Get started like this:

#[derive(bitbag::Flags)]
#[repr(u8)]
enum MyFlags {
    A = 0b0001,
    B = 0b0010,
    C = 0b0100,
}

Basic functionality is provided by Flags

let mut bag = bitbag::BitBag::<MyFlags>::new_unchecked(0b0011);
assert!(bag.is_set(MyFlags::A));
assert!(bag.is_set(MyFlags::B));
assert!(!bag.is_set(MyFlags::C));

bag.set(MyFlags::C);
assert_eq!(bag.repr(), 0b0111);

Deriving BitOr will also give you very ergonomic constructors

#[derive(bitbag::BitOr)]
enum MyFlags { ... }
use MyFlags::*;
let bag = A | B | C;
assert!(bag.is_set(MyFlags::A));
assert!(bag.is_set(MyFlags::B));
assert!(bag.is_set(MyFlags::C));

You can also choose to reject unrecognised bits, and iterate over the set flags.

let e = bitbag::BitBag::<MyFlags>::new_checked(0b1000).unwrap_err();
assert_eq!(e.to_string(), "The bits 0b1000 are not accounted for in MyFlags");

let bag = bitbag::BitBag::<MyFlags>::new_checked(0b0110).unwrap();
for flag in bag {
    match flag {
        MyFlags::A => println!("Flag A was set"),
        MyFlags::B => println!("Flag B was set"),
        MyFlags::C => println!("Flag C was set"),
    }
};

Dependencies

~205–640KB
~15K SLoC