#bitflags #enum #derive #scoped #hash


A bitmask generator for enum scoped bit flags

6 releases (breaking)

Uses old Rust 2015

0.5.0 Mar 18, 2019
0.4.0 May 7, 2017
0.3.0 Jan 31, 2017
0.2.0 Jan 22, 2017
0.1.1 Jan 21, 2017

#499 in Rust patterns

Download history 384/week @ 2022-08-14 401/week @ 2022-08-21 310/week @ 2022-08-28 484/week @ 2022-09-04 384/week @ 2022-09-11 549/week @ 2022-09-18 441/week @ 2022-09-25 545/week @ 2022-10-02 347/week @ 2022-10-09 221/week @ 2022-10-16 401/week @ 2022-10-23 425/week @ 2022-10-30 543/week @ 2022-11-06 317/week @ 2022-11-13 413/week @ 2022-11-20 236/week @ 2022-11-27

1,573 downloads per month
Used in 75 crates (3 directly)


642 lines


A bitmask generator for enum scoped bit flags



Add bitmask as a dependency in your Cargo.toml:

bitmask = "^0.5.0"

Then add this snippet to your crate's root:

extern crate bitmask;


Bitmask supports one feature: std. This is enabled by default, and will draw in the standard library and also automatically derive of Hash and Debug for generated types. If you prefer not to derive these features, then ensure you do not enable the default features.


Run a specific example with cargo run --example <name>.

Similar crates


A bitmask generator for enum scoped bit flags.

The bitmask! macro creates a struct and an enum that holds your flags. The enum contains all the bit flag variants and the struct is a mixture of those bit flags called a bitmask. It's syntax is as follows:

bitmask! {
    pub mask <struct_name>: <struct_type> where flags <enum_name> {
        <flag_name> = <value>,

where pub is optional and struct_type can be one of the primitive integer types (i8-64, u8-64, isize, usize).


Sometimes you might want to wrap some lib that ports C or some other code through FFI which exposes numerous defines/constants as const. Lets take a look at this example module:

mod tex {
    pub const TEXTURE_2D: u32   = 1;
    pub const TEXTURE_3D: u32   = 2;
    pub const FLIP: u32         = 4;
    pub fn set_options(mask: u32) { ... }

To avoid collisions you would use these through the mod scope like so:

tex::set_options(tex::TEXTURE_2D | tex::FLIP);

But that does not guarantee you that you won't use invalid flag values. For example you could do:

set_options(3 | 8);

Now imagine you had an enum to hold all of those flags and a common type that does not accept any types other than the enum variants and itself. This is exactly what bitmask! does for you! It generates an enum with the variants (flags) you supply and a struct that holds a mask which is a mixture of these variants. So now our example would look like this:

# mod tex {
#     pub const TEXTURE_2D: u32   = 1;
#     pub const TEXTURE_3D: u32   = 2;
#     pub const FLIP: u32         = 4;
#     pub fn set_options(mask: u32) {}
# }
# #[macro_use] extern crate bitmask; fn main() {
bitmask! {
    pub mask TexMask: u32 where flags TexOption {
        Texture2d = tex::TEXTURE_2D,
        Texture3d = tex::TEXTURE_3D,
        Flip = tex::FLIP

fn set_options(mask: TexMask) {

// Single flag

// Multiple flags
set_options(TexOption::Texture2d | TexOption::Flip);
# }

Things that are doable but can change with time:

If for some reason you want to define the enum and the struct yourself you can do so and use the @IMPL branch of the macro to implement the methods. The only restrictions are that your struct's inner field must be named mask and the enum should have the same size as the struct which can be achieved through the #[repr()] modifier with the same integer type as the field mask.

Implementing Into<struct_name> and Deref for your own custom type is possible if you want to use it with the preimplemented methods for the mask but does not apply for the trait implements like BitOr for example.


# #[macro_use] extern crate bitmask; fn main() {
bitmask! {
    mask BitMask: u32 where flags Flags {
        Flag1       = 0x00000001,
        Flag2       = 0x000000F0,
        Flag3       = 0x00000800,
        Flag123     = 0x000008F1,
        // Note that function calls like `isize::min_value()`
        // can't be used for enum discriminants in Rust.
        FlagMax     = ::std::u32::MAX

let mut mask = BitMask::none();

mask.set(Flags::Flag1 | Flags::Flag2);
assert_eq!(*mask, 0x000000F1);

assert_eq!(*mask, 0x000000F0);

assert_eq!(*mask, 0x000008F1);
# }

You can add meta attributes like documentation (#[doc = "..."]) to each element of the macro:

# #[macro_use] extern crate bitmask; fn main() {
bitmask! {
    /// Doc comment for the struct
    pub mask SomeOtherMask: isize where
    /// Doc comment for the enum
    flags SomeOtherFlags {
        /// Doc comment for the flag
        FlagZero    = 0,
        FlagOne     = 1
# }

Maybe not the best example but still... Cake is love!

# #[macro_use] extern crate bitmask; fn main() {
bitmask! {
    mask Cake: u8 where flags Ingredients {
        Sugar   = 0b00000001,
        Eggs    = 0b00000010,
        Flour   = 0b00000100,
        Milk    = 0b00001000

let quality_cake = Cake::all();
assert_eq!(*quality_cake, 0b00001111);
# }

No runtime deps


  • std