File: README.md

package info (click to toggle)
rust-enumflags2 0.7.10-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 160 kB
  • sloc: makefile: 4
file content (105 lines) | stat: -rw-r--r-- 3,877 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
[![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE-MIT)
[![LICENSE](https://img.shields.io/badge/license-apache-blue.svg)](LICENSE-APACHE)
[![Documentation](https://docs.rs/enumflags2/badge.svg)](https://docs.rs/enumflags2)
[![Crates.io Version](https://img.shields.io/crates/v/enumflags2.svg)](https://crates.io/crates/enumflags2)

# Enumflags

`enumflags2` implements the classic bitflags datastructure. Annotate an enum
with `#[bitflags]`, and `BitFlags<YourEnum>` will be able to hold arbitrary combinations
of your enum within the space of a single integer.

## Features

- [x] Uses enums to represent individual flags&mdash;a set of flags is a separate type from a single flag.
- [x] Automatically chooses a free bit when you don't specify.
- [x] Detects incorrect BitFlags at compile time.
- [x] Has a similar API compared to the popular [bitflags](https://crates.io/crates/bitflags) crate.
- [x] Does not expose the generated types explicity. The user interacts exclusively with `struct BitFlags<Enum>;`.
- [x] The debug formatter prints the binary flag value as well as the flag enums: `BitFlags(0b1111, [A, B, C, D])`.
- [x] Optional support for serialization with the [`serde`](https://serde.rs/) feature flag.

## Example

```rust
use enumflags2::{bitflags, make_bitflags, BitFlags};

#[bitflags]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum Test {
    A = 0b0001,
    B = 0b0010,
    C, // unspecified variants pick unused bits automatically
    D = 0b1000,
}

// Flags can be combined with |, this creates a BitFlags of your type:
let a_b: BitFlags<Test> = Test::A | Test::B;
let a_c = Test::A | Test::C;
let b_c_d = make_bitflags!(Test::{B | C | D});

// The debug output lets you inspect both the numeric value and
// the actual flags:
assert_eq!(format!("{:?}", a_b), "BitFlags<Test>(0b11, A | B)");

// But if you'd rather see only one of those, that's available too:
assert_eq!(format!("{}", a_b), "A | B");
assert_eq!(format!("{:04b}", a_b), "0011");

// Iterate over the flags like a normal set
assert_eq!(a_b.iter().collect::<Vec<_>>(), &[Test::A, Test::B]);

// Query the contents with contains and intersects
assert!(a_b.contains(Test::A));
assert!(b_c_d.contains(Test::B | Test::C));
assert!(!(b_c_d.contains(a_b)));

assert!(a_b.intersects(a_c));
assert!(!(a_b.intersects(Test::C | Test::D)));
```

## Optional Feature Flags

- [`serde`](https://serde.rs/) implements `Serialize` and `Deserialize`
  for `BitFlags<T>`.
- `std` implements `std::error::Error` for `FromBitsError`.

## `const fn`-compatible APIs

**Background:** The subset of `const fn` features currently stabilized is pretty limited.
Most notably, [const traits are still at the RFC stage][const-trait-rfc],
which makes it impossible to use any overloaded operators in a const
context.

**Naming convention:** If a separate, more limited function is provided
for usage in a `const fn`, the name is suffixed with `_c`.

**Blanket implementations:** If you attempt to write a `const fn` ranging
over `T: BitFlag`, you will be met with an error explaining that currently,
the only allowed trait bound for a `const fn` is `?Sized`. You will probably
want to write a separate implementation for `BitFlags<T, u8>`,
`BitFlags<T, u16>`, etc — probably generated by a macro.
This strategy is often used by `enumflags2` itself; to avoid clutter, only
one of the copies is shown in the documentation.

## Customizing `Default`

By default, creating an instance of `BitFlags<T>` with `Default` will result in an empty
set. If that's undesirable, you may customize this:

```rust
#[bitflags(default = B | C)]
#[repr(u8)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum Test {
    A = 0b0001,
    B = 0b0010,
    C = 0b0100,
    D = 0b1000,
}

assert_eq!(BitFlags::default(), Test::B | Test::C);
```

[const-trait-rfc]: https://github.com/rust-lang/rfcs/pull/2632