5 个版本
0.2.1 | 2020 年 12 月 29 日 |
---|---|
0.2.0 | 2020 年 12 月 29 日 |
0.1.2 | 2020 年 12 月 29 日 |
0.1.1 | 2020 年 12 月 29 日 |
0.1.0 | 2020 年 12 月 29 日 |
#1433 in Rust 模式
用于 termorrow
5KB
88 行
flag-mast
人体工程学 Rust 位标志
用法
flag-mast
包提供了一个 derive 宏,帮助创建符合人体工程学的 C 兼容位标志。
示例
use flag_mast::*;
#[derive(Flags, Default)]
#[flag(name = "BARKS", method_name = "can_bark", value = 0x1)]
#[flag(name = "SITS", method_name = "can_sit", value = 0x2)]
#[flag(name = "BROWN", method_name = "is_brown", value = 0x4)]
struct Dog(#[flag_backing_field] u32);
fn foo() {
let mut dog = Dog::default();
dog.set_can_bark(true)
.set_can_sit(false)
.set_is_brown(true);
if dog.is_brown() {
println!("Cute doggo!");
} else {
println!("Doggo is not brown, but is cute anyway");
}
}
derive 宏不会改变结构体的底层布局,甚至可以是 repr(C)
!。
name
参数是标志的规范名称,它不需要是一个有效的 Rust 标识符或遵循 Rust 命名惯例。
如果 name
参数 是 作为 Rust 标识符适当的(并且你不想自定义或前缀它),则可以省略 method_name
参数。
value
参数可以是整数字面量或包含求解标志值的表达式的字符串。
value
不必与支持字段具有相同的精确类型,只需可转换为该类型。
flag_backing_field
属性指定结构体中用于存储位标志的字段。
这意味着我们也可以有
use flag_mast::*;
const BLUE: u8 = 0x1;
const RED: u8 = 0x2;
mod secondary_colours {
pub const YELLOW: u16 = 0x4;
}
#[derive(Flags, Default)]
#[flag(name = "blue", value = "BLUE")]
#[flag(name = "red", value = "RED")]
#[flag(name = "yellow", value = "secondary_colours::YELLOW")]
#[flag(name = "purple", value = "BLUE & RED")]
#[flag(name = "black", value = 0x8)]
#[repr(C)]
struct Colour{
is_useful: bool,
#[flag_backing_field]
flags: u32
}
fn bar() {
let mut colour = Colour::default();
colour.set_blue(true);
colour.set_red(true);
if colour.purple() {
println("That's red AND blue!");
}
}
自动 Debug 实现
derive 宏还可以自动为你生成一个符合你标志的 Debug
实现。这种行为由一个额外的属性控制。
use flag_mast::*;
#[derive(Flags, Default)]
#[flag_debug]
#[flag(name = "one", value = 4)]
#[flag(name = "second", method_name = "two", value = 8)]
#[flag(name = "three", value = 16)]
struct Buttons(#[flag_backing_field] u16)
fn baz() {
let mut buttons = Buttons::default();
buttons.set_one(true);
println!("{:?}", buttons);
println!("---");
println!("{:#?}", buttons);
}
这将打印(注意使用的是 方法名称)
Buttons { one: true, two: false, three: true }
---
Buttons {
one: true,
two: false,
three: false
}
你也可以通过指定 flag_debug
属性的 compact
参数来选择(可能)更紧凑的调试格式。此格式仅显示已设置的标志。
use flag_mast::*;
#[derive(Flags, Default)]
#[flag_debug(compact)]
#[flag(name = "one", value = 4)]
#[flag(name = "second", method_name = "two", value = 8)]
#[flag(name = "three", value = 16)]
struct Buttons(#[flag_backing_field] u16)
fn baz() {
let mut buttons = Buttons::default();
buttons.set_one(true);
buttons.set_two(true);
println!("{:?}", buttons);
println!("---");
println!("{:#?}", buttons);
}
这将打印(注意使用的是 名称)
Buttons { "one", "second" }
---
Buttons {
"one",
"second",
}
许可证
flag-mast
在 MIT 许可证和 Apache 2.0 许可证下双许可。你可以选择你喜欢的任何一个。
依赖项
~1.5MB
~36K SLoC