#bit-field #bit #struct #macro #proc-macro #statically-typed

无 std bit-struct

定义具有按位分配字段的 struct,而不是按字节分配

37 个版本

0.4.0 2023 年 3 月 2 日
0.3.1 2023 年 2 月 7 日
0.3.0 2022 年 11 月 8 日
0.1.31 2022 年 1 月 25 日
0.1.2 2021 年 11 月 30 日

#38无标准库

Download history 926/week @ 2024-04-20 802/week @ 2024-04-27 607/week @ 2024-05-04 420/week @ 2024-05-11 758/week @ 2024-05-18 614/week @ 2024-05-25 538/week @ 2024-06-01 770/week @ 2024-06-08 602/week @ 2024-06-15 1148/week @ 2024-06-22 492/week @ 2024-06-29 804/week @ 2024-07-06 675/week @ 2024-07-13 704/week @ 2024-07-20 654/week @ 2024-07-27 475/week @ 2024-08-03

2,696 每月下载次数
canopen_rust 中使用

MIT/Apache

66KB
1.5K SLoC

bit-struct

crates.io codecov Minimum rustc version

Bit struct 是一个 crate,允许以可用的方式使用类似 C 的位域,而无需 proc macros 引起的低效 IDE 支持。此外,所有内容都是静态类型检查的!

以下是一个示例

use bit_struct::*; 

enums! {
    // 2 bits, i.e., 0b00, 0b01, 0b10
    pub HouseKind { Urban, Suburban, Rural}
}

bit_struct! {
    // u8 is the base storage type. This can be any multiple of 8
    pub struct HouseConfig(u8) {
        // 2 bits
        kind: HouseKind,
        
        // two's compliment 3-bit signed number
        lowest_floor: i3,
        
        // 2 bit unsigned number
        highest_floor: u2,
    }
}

// We can create a new `HouseConfig` like such:
// where all numbers are statically checked to be in bounds.
let config = HouseConfig::new(HouseKind::Suburban, i3!(-2), u2!(1));

// We can get the raw `u8` which represents `config`:
let raw: u8 = config.raw();
assert_eq!(114_u8, raw);

// or we can get a `HouseConfig` from a `u8` like:
let mut config: HouseConfig = HouseConfig::try_from(114_u8).unwrap();
assert_eq!(config, HouseConfig::new(HouseKind::Suburban, i3!(-2), u2!(1)));
// We need to unwrap because `HouseConfig` is not valid for all numbers. For instance, if the
// most significant bits are `0b11`, it encodes an invalid `HouseKind`. However, 
// if all elements of a struct are always valid (suppose we removed the `kind` field), the struct will
// auto implement a trait which allows calling the non-panicking:
// let config: HouseConfig = HouseConfig::exact_from(123_u8);

// We can access values of `config` like so:
let kind: HouseKind = config.kind().get();

// And we can set values like so:
config.lowest_floor().set(i3!(0));

// We can also convert the new numeric types for alternate bit-widths into the 
// numeric types provided by the standard library:
let lowest_floor: i3 = config.lowest_floor().get();
let lowest_floor_std: i8 = lowest_floor.value();
assert_eq!(lowest_floor_std, 0_i8);

优势

  • 无 proc macros
  • 自动完成功能完全正常(在 IntelliJ Rust 中测试过)
  • 快速编译时间
  • 静态检查 struct 是否溢出。例如,以下溢出的 struct 将无法编译
      bit_struct::bit_struct! {
          struct TooManyFieldsToFit(u16) {
              a: u8,
              b: u8,
              c: bit_struct::u1
          }
      }
    
      bit_struct::bit_struct! {
          struct FieldIsTooBig(u16) {
              a: u32
          }
      }
    
  • 静态检查的类型

更多文档

请查看 tests 文件夹中的集成测试以获取更多信息。

依赖项

~0.5–1.1MB
~25K SLoC