Bit fields and masks for rust!
Provides a macro for generating bit field
types
complete with flags and some helpful trait implementations.
Supports field widths of 8
, 16
, 32
, 64
and 128
bits.
bitfield
] - macro documentation.examples
] - examples of the output generated by the [bitfield
] macro.Note: the example module is only complied with documentation builds and is not available for importing in the wild.
Generate a bitfield struct with a flag enum... (The following examples all use this as a definition.) ```rust use ubits::bitfield;
bitfield! {
pub u8 ExampleField
ExampleFlags {
0 : Flag0
1 : Flag1
2 : Flag2
3 : Flag3
4 : Flag4
5 : Flag5
6 : Flag6
7 : Flag7
}
}
```
From integer: ```rust
let frominteger = ExampleField(123); asserteq!(ExampleField(123), from_integer); ```
From a binary string: ```rust
let frombinary = ExampleField::frombinarystr("01111011"); asserteq!(ExampleField(123), from_binary) ```
From ones: ```rust
let fromones = ExampleField::ones(); asserteq!("11111111", fromones.asbinary()); asserteq!(255, fromones.as_integer()); ```
From zeros: ```rust
let fromzeros = ExampleField::zeros(); asserteq!("00000000", fromzeros.asbinary()); asserteq!(0, fromzeros.as_integer()); ```
Get bit value by field: ```rust
let field = ExampleField::frombinarystr("01010101"); assert!(field.get(ExampleFlags::Flag0)); assert!(!field.get(ExampleFlags::Flag1)); ```
Get bit value by index:
```rust
let field = ExampleField::frombinarystr("01010101"); assert!(field.getindex(0)); assert!(!field.getindex(1)); ```
Set bit value by field:
```rust
let mut field = ExampleField::frombinarystr("01010101"); field.set(ExampleFlags::Flag1); field.set(ExampleFlags::Flag3); asserteq!("01011111", field.asbinary()); ```
Set bit value by index:
```rust
let mut field = ExampleField::frombinarystr("01010101"); field.setindex(1); field.setindex(3); asserteq!("01011111", field.asbinary()); ```
Clear bit value by field:
```rust
let mut field = ExampleField::frombinarystr("01010101"); field.clear(ExampleFlags::Flag0); field.clear(ExampleFlags::Flag2); asserteq!("01010000", field.asbinary()); ```
Clear bit value by index:
```rust
let mut field = ExampleField::frombinarystr("01010101"); field.clearindex(0); field.clearindex(2); asserteq!("01010000", field.asbinary()); ```
Toggle bit value by field:
```rust
let mut field = ExampleField::frombinarystr("01010101"); field.toggle(ExampleFlags::Flag0); asserteq!("01010100", field.asbinary()); field.toggle(ExampleFlags::Flag0); asserteq!("01010101", field.asbinary()); ```
Toggle bit value by index:
```rust
let mut field = ExampleField::frombinarystr("01010101"); field.toggleindex(0); asserteq!("01010100", field.asbinary()); field.toggleindex(0); asserteq!("01010101", field.asbinary()); ```
Combine bit fields:
(use into_combined
to consume self)
```rust
let mut a = ExampleField::frombinarystr("01010101"); let b = ExampleField::frombinarystr("10101010"); asserteq!("11111111", a.combine(b).asbinary()); ```
Get the intersection of two bitfields:
(use into_intersection
to consume self)
```rust
let mut a = ExampleField::frombinarystr("11000011"); let b = ExampleField::frombinarystr("01111110"); asserteq!("01000010", a.intersect(b).asbinary()); ```
Get the diff of two bitfields:
(use into_diff
to consume self)
```rust
let mut a = ExampleField::frombinarystr("11000011"); let b = ExampleField::frombinarystr("01100110"); asserteq!("10100101", a.diff(b).asbinary()); ```
Both bit field instances and flags use bitwise operators to change bit values.
```rust
let mut fromzeros = ExampleField::zeros(); asserteq!("00000000", fromzeros.asbinary());
// set bit to 1 fromzeros |= ExampleFlags::Flag1; asserteq!("00000010", fromzeros.asbinary());
// set bit back to 0 fromzeros &= ExampleFlags::Flag1; asserteq!("00000000", fromzeros.asbinary());
// toggle a bit fromzeros ^= ExampleFlags::Flag1; asserteq!("00000010", fromzeros.asbinary());
fromzeros ^= ExampleFlags::Flag1; asserteq!("00000000", fromzeros.asbinary()); ```
Operations can also be chained together:
```rust
let mut fromzeros = ExampleField::zeros() | ExampleFlags::Flag1 | ExampleFlags::Flag3; asserteq!("00001010", fromzeros.asbinary());
```
Bitfield instances can also be created from combining flags:
```rust
let mut fromzeros = ExampleFlags::Flag1 | ExampleFlags::Flag3; asserteq!("00001010", fromzeros.asbinary());
```
The generated flags enum allows you to access bits by name.
The flag has an associated [u8
] value,
which determines the index its target bit.
(See [bitfield
] for more info)
With the following input...
no_compile
1 0 1 0 0 1 1 0
and the following flags...
no_compile
0 : f1
1 : f1
2 : f2
3 : f3
4 : f4
5 : f5
6 : f6
7 : f7
we end up with this layout.
| name | f7 | f6 | f5 | f4 | f3 | f2 | f1 | f0 | |-----------|----|----|----|----|----|----|----|----| | bit value | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | | index | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
With the same input and only the first few flags:
no_compile
0 : f0
1 : f1
2 : f2
we end up with this layout.
| name | | | | | | f2 | f1 | f0 | |-----------|----|----|----|----|----|----|----|----| | bit value | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | | index | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Using the same input, but with dispersed flags:
no_compile
1 : f0
3 : f1
6 : f2
we end up with this layout.
| name | | f2 | | | f1 | | f0 | | |-----------|----|----|----|----|----|----|----|----| | bit value | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | | index | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |