#bitflags #bitmask #bit

无std 标志

一个宏,用于生成类似于位标志的结构体

7个版本

使用旧的Rust 2015

0.1.5 2020年12月22日
0.1.4 2020年2月1日
0.1.3 2018年12月6日
0.1.2 2018年10月8日
0.0.0 2018年4月21日

192无标准库

Download history 31/week @ 2024-03-24 64/week @ 2024-03-31 27/week @ 2024-04-07 33/week @ 2024-04-14 40/week @ 2024-04-21 38/week @ 2024-04-28 30/week @ 2024-05-05 35/week @ 2024-05-12 37/week @ 2024-05-19 21/week @ 2024-05-26 25/week @ 2024-06-02 16/week @ 2024-06-09 31/week @ 2024-06-16 28/week @ 2024-06-23 6/week @ 2024-06-30 13/week @ 2024-07-07

78 每月下载量
10 个crate中(7个直接)使用

MIT/Apache

38KB
750

一个用于C样式位掩码标志集合的类型安全位掩码标志生成器。它可以用于在C API周围创建类型安全的包装器。

bitflags! 宏生成一个管理一组标志的 struct。标志应仅针对整数类型定义,否则在编译时可能会出现意外的类型错误。

示例

extern crate bitflags;

bitflags::bitflags! {
    struct Flags: u32 {
        const A = 0b00000001;
        const B = 0b00000010;
        const C = 0b00000100;
        const ABC = Self::A.bits | Self::B.bits | Self::C.bits;
    }
}

fn main() {
    let e1 = Flags::A | Flags::C;
    let e2 = Flags::B | Flags::C;
    assert_eq!((e1 | e2), Flags::ABC);   // union
    assert_eq!((e1 & e2), Flags::C);     // intersection
    assert_eq!((e1 - e2), Flags::A);     // set difference
    assert_eq!(!e2, Flags::A);           // set complement
}

有关上述 bitflags! 扩展生成的代码的文档,请参阅 example_generated::Flags

生成的 struct 也可以通过类型和特性实现进行扩展

extern crate bitflags;

use std::fmt;

bitflags::bitflags! {
    struct Flags: u32 {
        const A = 0b00000001;
        const B = 0b00000010;
    }
}

impl Flags {
    pub fn clear(&mut self) {
        self.bits = 0;  // The `bits` field can be accessed from within the
                        // same module where the `bitflags!` macro was invoked.
    }
}

impl fmt::Display for Flags {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "hi!")
    }
}

fn main() {
    let mut flags = Flags::A | Flags::B;
    flags.clear();
    assert!(flags.is_empty());
    assert_eq!(format!("{}", flags), "hi!");
    assert_eq!(format!("{:?}", Flags::A | Flags::B), "A | B");
    assert_eq!(format!("{:?}", Flags::B), "B");
}

可见性

默认情况下,生成的结构和相关的标志常量不会被导出至当前模块之外。可以通过在 flags 前添加 pub 将定义导出至当前模块之外。

extern crate bitflags;

mod example {
    bitflags::bitflags! {
        pub struct Flags1: u32 {
            const A = 0b00000001;
        }
    }
    bitflags::bitflags! {
        struct Flags2: u32 {
            const B = 0b00000010;
        }
    }
}

fn main() {
    let flag1 = example::Flags1::A;
    let flag2 = example::Flags2::B; // error: const `B` is private
}

属性

可以通过在 flags 关键字之前放置它们来将属性附加到生成的 struct

特性实现

CopyClonePartialEqEqHash 特性通过使用 derive 属性自动派生到 struct。可以通过在 flags 上提供显式的 derive 属性来派生其他特性。

struct 实现了 ExtendFromIterator 特性:Extend 添加了迭代过的 struct 实例的并集,而 FromIterator 计算并集。

通过显示内部结构的位值,还实现了 BinaryDebugLowerExpOctalUpperExp 特性。

运算符

为生成的 struct 实现了以下运算符特性

  • BitOrBitOrAssign:并集
  • BitAndBitAndAssign:交集
  • BitXorBitXorAssign:切换
  • SubSubAssign:集合差
  • Not:集合补

方法

以下方法定义于生成的 struct

  • empty:空的标志集合
  • all:所有标志的集合
  • bits:当前存储的标志的原始值
  • from_bits:从底层的位表示转换,除非该表示包含不对应于标志的位
  • from_bits_truncate:从底层的位表示转换,丢弃任何不对应于标志的位
  • is_empty:如果没有存储任何标志,返回 true
  • is_all:如果所有标志都已设置,返回 true
  • intersects:如果 selfother 有共同的标志,返回 true
  • contains:如果 other 中的所有标志都包含在 self 中,返回 true
  • insert:就地插入指定的标志
  • remove:就地移除指定的标志
  • toggle:如果指定的标志不存在,则将其插入;如果已存在,则将其移除
  • set:根据传入的值插入或移除指定的标志

默认值

生成的结构体不会自动实现 Default 特性。

如果您的默认值等于 0(这等于在生成的结构体上调用 empty()),您可以直接派生 Default

extern crate bitflags;

bitflags::bitflags! {
    // Results in default value with bits: 0
    #[derive(Default)]
    struct Flags: u32 {
        const A = 0b00000001;
        const B = 0b00000010;
        const C = 0b00000100;
    }
}

fn main() {
    let derived_default: Flags = Default::default();
    assert_eq!(derived_default.bits(), 0);
}

如果您的默认值不等于 0,则需要自己实现 Default

extern crate bitflags;

bitflags::bitflags! {
    struct Flags: u32 {
        const A = 0b00000001;
        const B = 0b00000010;
        const C = 0b00000100;
    }
}

// explicit `Default` implementation
impl Default for Flags {
    fn default() -> Flags {
        Flags::A | Flags::C
    }
}

fn main() {
    let implemented_default: Flags = Default::default();
    assert_eq!(implemented_default, (Flags::A | Flags::C));
}

无运行时依赖

特性