[dependencies.num_enum]
version = "0.7.2"
default-features = false # to disable std feature
#![allow(unused)]
fn main() {
use num_enum::{IntoPrimitive, TryFromPrimitive};
#[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Eq)]
#[repr(u8)]
enum Status {
OUTB = 0x01,
INPB = 0x02,
AUXB = 0x20, // this may be wrong here.
}
// ...
if let Ok(s) = Status::try_from(var_uint8) {
// deal with s::Status
} else {
// deal with conversion error
}
```
### bitflags
https://docs.rs/bitflags/latest/bitflags/
https://docs.rs/bitflags/latest/bitflags/trait.Flags.html
**Cautions**
- **Flags with no bits set should be avoided!!!*** Interact strangely with Flags::
contains and Flags::intersects. A zero-bit flag is always contained but never
intersected. The names of zero-bit flags are never formatted.
- **Flags that set multiple bits should be avoided unless each bit is also in a
single-bit flag**
**Usage**
Cargo.toml
```
[dependencies.bitflags]
version = "2.4.2"
```
```rust
// basic
use bitflags::bitflags;
bitflags! {
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Flags: u32 {
const A = 0b00000001;
const B = 0b00000010;
const C = 0b00000100;
// specify ALL bits as known bits.
// use this for externally defined flags
const _ = !0;
}
}
// with custom methods:
impl Flags {
pub fn as_u64(&self) -> u64 {
self.bits() as u64
}
}
// using:
let ab = Flags::A | Flags::B; // union
let a = ab & Flags::A; // intersection
let b = ab - Flags::A; // difference
let c = !ab; // complement
```
Derives:
- Debug, Clone, Copy, PartialEq, Eq, Hash ...
**Terminology**
```
bitflags! {
struct FlagsType: u8 {
| |_ Bits type
|
+------- Flags type
const A = 1;
|____ Flag
}
}
let flag = FlagsType::A;
|___ Flags value
```
**Known and unknown bits**
Defined bits are 'known bits', otherwise 'unknown bits'. Operators may **unset**
any unknown bits they encounter.
```rust
bitflags! {
struct Flags: u8 {
const A = 1;
const B = 1 << 1;
const C = 1 << 2;
}
}
// known bits: 0b0000_0111
// unknown bits: 0b1111_1000
```
}