Crate bit_struct

source ·
Expand description

bit-struct

crates.io codecov Minimum rustc version

Bit struct is a crate which allows for ergonomic use of C-like bit fields without mediocre IDE support resulting from proc macros. In addition, everything is statically typed checked!

Take the following example

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);

Benefits

  • No proc macros
  • Autocompletion fully works (tested in IntelliJ Rust)
  • Fast compile times
  • Statically checks that structs are not overfilled. For example, these overfilled structs will not compile:
      bit_struct::bit_struct! {
          struct TooManyFieldsToFit(u16) {
              a: u8,
              b: u8,
              c: bit_struct::u1
          }
      }
      bit_struct::bit_struct! {
          struct FieldIsTooBig(u16) {
              a: u32
          }
      }
  • Statically checked types

Further Documentation

Look at the integration tests in the tests folder for further insight.

Macros

Create a bit struct.
Create a bit_struct
Create enums with trait implementations necessary for use in a bit_struct field.
Produce a value of type i2
Produce a value of type i3
Produce a value of type i4
Produce a value of type i5
Produce a value of type i6
Produce a value of type i7
Produce a value of type i9
Produce a value of type i10
Produce a value of type i11
Produce a value of type i12
Produce a value of type i13
Produce a value of type i14
Produce a value of type i15
Produce a value of type i17
Produce a value of type i18
Produce a value of type i19
Produce a value of type i20
Produce a value of type i21
Produce a value of type i22
Produce a value of type i23
Produce a value of type i24
Produce a value of type i25
Produce a value of type i26
Produce a value of type i27
Produce a value of type i28
Produce a value of type i29
Produce a value of type i30
Produce a value of type i31
Produce a value of type i33
Produce a value of type i34
Produce a value of type i35
Produce a value of type i36
Produce a value of type i37
Produce a value of type i38
Produce a value of type i39
Produce a value of type i40
Produce a value of type i41
Produce a value of type i42
Produce a value of type i43
Produce a value of type i44
Produce a value of type i45
Produce a value of type i46
Produce a value of type i47
Produce a value of type i48
Produce a value of type i49
Produce a value of type i50
Produce a value of type i51
Produce a value of type i52
Produce a value of type i53
Produce a value of type i54
Produce a value of type i55
Produce a value of type i56
Produce a value of type i57
Produce a value of type i58
Produce a value of type i59
Produce a value of type i60
Produce a value of type i61
Produce a value of type i62
Produce a value of type i63
Produce a value of type u1
Produce a value of type u2
Produce a value of type u3
Produce a value of type u4
Produce a value of type u5
Produce a value of type u6
Produce a value of type u7
Produce a value of type u9
Produce a value of type u10
Produce a value of type u11
Produce a value of type u12
Produce a value of type u13
Produce a value of type u14
Produce a value of type u15
Produce a value of type u17
Produce a value of type u18
Produce a value of type u19
Produce a value of type u20
Produce a value of type u21
Produce a value of type u22
Produce a value of type u23
Produce a value of type u24
Produce a value of type u25
Produce a value of type u26
Produce a value of type u27
Produce a value of type u28
Produce a value of type u29
Produce a value of type u30
Produce a value of type u31
Produce a value of type u33
Produce a value of type u34
Produce a value of type u35
Produce a value of type u36
Produce a value of type u37
Produce a value of type u38
Produce a value of type u39
Produce a value of type u40
Produce a value of type u41
Produce a value of type u42
Produce a value of type u43
Produce a value of type u44
Produce a value of type u45
Produce a value of type u46
Produce a value of type u47
Produce a value of type u48
Produce a value of type u49
Produce a value of type u50
Produce a value of type u51
Produce a value of type u52
Produce a value of type u53
Produce a value of type u54
Produce a value of type u55
Produce a value of type u56
Produce a value of type u57
Produce a value of type u58
Produce a value of type u59
Produce a value of type u60
Produce a value of type u61
Produce a value of type u62
Produce a value of type u63

Structs

A struct which allows for getting/setting a given property
UnsafeStorage is used to mark that there are some arbitrary invariants which must be maintained in storing its inner value. Therefore, creation and modifying of the inner value is an “unsafe” behavior. Although it might not be unsafe in traditional Rust terms (no memory unsafety), behavior might be “undefined”—or at least undocumented, because invariants are expected to be upheld.
An unsigned integer which contains 2 bits
An unsigned integer which contains 3 bits
An unsigned integer which contains 4 bits
An unsigned integer which contains 5 bits
An unsigned integer which contains 6 bits
An unsigned integer which contains 7 bits
An unsigned integer which contains 9 bits
An unsigned integer which contains 10 bits
An unsigned integer which contains 11 bits
An unsigned integer which contains 12 bits
An unsigned integer which contains 13 bits
An unsigned integer which contains 14 bits
An unsigned integer which contains 15 bits
An unsigned integer which contains 17 bits
An unsigned integer which contains 18 bits
An unsigned integer which contains 19 bits
An unsigned integer which contains 20 bits
An unsigned integer which contains 21 bits
An unsigned integer which contains 22 bits
An unsigned integer which contains 23 bits
An unsigned integer which contains 24 bits
An unsigned integer which contains 25 bits
An unsigned integer which contains 26 bits
An unsigned integer which contains 27 bits
An unsigned integer which contains 28 bits
An unsigned integer which contains 29 bits
An unsigned integer which contains 30 bits
An unsigned integer which contains 31 bits
An unsigned integer which contains 33 bits
An unsigned integer which contains 34 bits
An unsigned integer which contains 35 bits
An unsigned integer which contains 36 bits
An unsigned integer which contains 37 bits
An unsigned integer which contains 38 bits
An unsigned integer which contains 39 bits
An unsigned integer which contains 40 bits
An unsigned integer which contains 41 bits
An unsigned integer which contains 42 bits
An unsigned integer which contains 43 bits
An unsigned integer which contains 44 bits
An unsigned integer which contains 45 bits
An unsigned integer which contains 46 bits
An unsigned integer which contains 47 bits
An unsigned integer which contains 48 bits
An unsigned integer which contains 49 bits
An unsigned integer which contains 50 bits
An unsigned integer which contains 51 bits
An unsigned integer which contains 52 bits
An unsigned integer which contains 53 bits
An unsigned integer which contains 54 bits
An unsigned integer which contains 55 bits
An unsigned integer which contains 56 bits
An unsigned integer which contains 57 bits
An unsigned integer which contains 58 bits
An unsigned integer which contains 59 bits
An unsigned integer which contains 60 bits
An unsigned integer which contains 61 bits
An unsigned integer which contains 62 bits
An unsigned integer which contains 63 bits
An unsigned integer which contains 1 bits
An unsigned integer which contains 2 bits
An unsigned integer which contains 3 bits
An unsigned integer which contains 4 bits
An unsigned integer which contains 5 bits
An unsigned integer which contains 6 bits
An unsigned integer which contains 7 bits
An unsigned integer which contains 9 bits
An unsigned integer which contains 10 bits
An unsigned integer which contains 11 bits
An unsigned integer which contains 12 bits
An unsigned integer which contains 13 bits
An unsigned integer which contains 14 bits
An unsigned integer which contains 15 bits
An unsigned integer which contains 17 bits
An unsigned integer which contains 18 bits
An unsigned integer which contains 19 bits
An unsigned integer which contains 20 bits
An unsigned integer which contains 21 bits
An unsigned integer which contains 22 bits
An unsigned integer which contains 23 bits
An unsigned integer which contains 24 bits
An unsigned integer which contains 25 bits
An unsigned integer which contains 26 bits
An unsigned integer which contains 27 bits
An unsigned integer which contains 28 bits
An unsigned integer which contains 29 bits
An unsigned integer which contains 30 bits
An unsigned integer which contains 31 bits
An unsigned integer which contains 33 bits
An unsigned integer which contains 34 bits
An unsigned integer which contains 35 bits
An unsigned integer which contains 36 bits
An unsigned integer which contains 37 bits
An unsigned integer which contains 38 bits
An unsigned integer which contains 39 bits
An unsigned integer which contains 40 bits
An unsigned integer which contains 41 bits
An unsigned integer which contains 42 bits
An unsigned integer which contains 43 bits
An unsigned integer which contains 44 bits
An unsigned integer which contains 45 bits
An unsigned integer which contains 46 bits
An unsigned integer which contains 47 bits
An unsigned integer which contains 48 bits
An unsigned integer which contains 49 bits
An unsigned integer which contains 50 bits
An unsigned integer which contains 51 bits
An unsigned integer which contains 52 bits
An unsigned integer which contains 53 bits
An unsigned integer which contains 54 bits
An unsigned integer which contains 55 bits
An unsigned integer which contains 56 bits
An unsigned integer which contains 57 bits
An unsigned integer which contains 58 bits
An unsigned integer which contains 59 bits
An unsigned integer which contains 60 bits
An unsigned integer which contains 61 bits
An unsigned integer which contains 62 bits
An unsigned integer which contains 63 bits

Traits

A trait which defines how many bits are needed to store a struct.
A trait that all bit structs implement
An extension trait for bit structs which can be safely made from any value in their underlying storage type.
A bit struct which has a zero value we can get
A conversion type for fitting the bits of one type into the bits of another type
A type which can be a field of a bit_struct
Check whether the underlying bits are valid

Functions

Returns the index of the leading 1 in num