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日 |
#22 in #bit-flags
用于 2 个crate(通过 flag-mast)
10KB
295 代码行
flag-mast
人体工程学Rust位标志
使用方法
“flag-mast”crate提供了一个衍生宏,用于帮助创建与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");
}
}
衍生宏不会改变结构体的底层布局,甚至可以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
实现。此行为由一个额外的属性控制。
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
}
你也可以通过指定compact
参数到flag_debug
属性来选择(可能)更紧凑的调试格式。此格式只显示已设置的标志。
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