Crate ubits

source · []
Expand description

crates.io Downloads Build Docs Licence

Bit fields and masks for rust!

Provides a macro for generating bit field types complete with flags and some helpful trait implementations.

Supports field widths of 8, 16, 32, 64 and 128 bits.

Note: the example module is only complied with documentation builds and is not available for importing in the wild.

Usage

Generate a bitfield struct with a flag enum… (The following examples all use this as a definition.)

use ubits::bitfield;

    bitfield! {
        pub u8 ExampleField
        ExampleFlags {
            0 : Flag0,
            1 : Flag1,
            2 : Flag2,
            3 : Flag3,
            4 : Flag4,
            5 : Flag5,
            6 : Flag6,
            7 : Flag7,
        }
    }

Instances

From integer:


let from_integer = ExampleField(123);
assert_eq!(ExampleField(123), from_integer);

From a binary string:


let from_binary = ExampleField::from_binary_str("01111011");
assert_eq!(ExampleField(123), from_binary)

From ones:


let from_ones = ExampleField::ones();
assert_eq!("11111111", from_ones.as_binary());
assert_eq!(255, from_ones.as_integer());

From zeros:


let from_zeros = ExampleField::zeros();
assert_eq!("00000000", from_zeros.as_binary());
assert_eq!(0, from_zeros.as_integer());

Field Access

Get bit value by field:


let field = ExampleField::from_binary_str("01010101");
assert!(field.get(ExampleFlags::Flag0));
assert!(!field.get(ExampleFlags::Flag1));

Get bit value by index:


let field = ExampleField::from_binary_str("01010101");
assert!(field.get_index(0));
assert!(!field.get_index(1));

Set bit value by field:


let mut field = ExampleField::from_binary_str("01010101");
field.set(ExampleFlags::Flag1);
field.set(ExampleFlags::Flag3);
assert_eq!("01011111", field.as_binary());

Set bit value by index:


let mut field = ExampleField::from_binary_str("01010101");
field.set_index(1);
field.set_index(3);
assert_eq!("01011111", field.as_binary());

Clear bit value by field:


let mut field = ExampleField::from_binary_str("01010101");
field.clear(ExampleFlags::Flag0);
field.clear(ExampleFlags::Flag2);
assert_eq!("01010000", field.as_binary());

Clear bit value by index:


let mut field = ExampleField::from_binary_str("01010101");
field.clear_index(0);
field.clear_index(2);
assert_eq!("01010000", field.as_binary());

Toggle bit value by field:


let mut field = ExampleField::from_binary_str("01010101");
field.toggle(ExampleFlags::Flag0);
assert_eq!("01010100", field.as_binary());
field.toggle(ExampleFlags::Flag0);
assert_eq!("01010101", field.as_binary());

Toggle bit value by index:


let mut field = ExampleField::from_binary_str("01010101");
field.toggle_index(0);
assert_eq!("01010100", field.as_binary());
field.toggle_index(0);
assert_eq!("01010101", field.as_binary());

Named Getters and Setters

Ubits can generate getter and setter methods for zero or more fields, if a name is provided.

use ubits::bitfield;
   bitfield! {
       pub u8 ExampleField
       ExampleFlags {
           0 : Flag0 : (field_0),  // is_field_0 & set_field_0 & clear_field_0 & toggle_field_0
           1 : Flag1 : (field_1),  // is_field_1 & set_field_1 & clear_field_1 & toggle_field_1
           2 : Flag2,
           3 : Flag3,
           4 : Flag4,
           5 : Flag5,
           6 : Flag6,
           7 : Flag7,
       }
   }

let mut field = ExampleField::from_binary_str("01010101");
assert_eq!(true, field.is_field_0());
assert_eq!(false, field.is_field_1());

field.set_field_1();
assert_eq!(true, field.is_field_1());

field.clear_field_1();
assert_eq!(false, field.is_field_1());

field.toggle_field_1();
assert_eq!(true, field.is_field_1());

Combinations

Combine bit fields:
(use into_combined to consume self)


let mut a = ExampleField::from_binary_str("01010101");
let b = ExampleField::from_binary_str("10101010");
assert_eq!("11111111", a.combine(b).as_binary());

Get the intersection of two bitfields:
(use into_intersection to consume self)


let mut a = ExampleField::from_binary_str("11000011");
let b = ExampleField::from_binary_str("01111110");
assert_eq!("01000010", a.intersect(b).as_binary());

Get the diff of two bitfields:
(use into_diff to consume self)


let mut a = ExampleField::from_binary_str("11000011");
let b = ExampleField::from_binary_str("01100110");
assert_eq!("10100101", a.diff(b).as_binary());

Bitwise

Both bit field instances and flags use bitwise operators to change bit values.


let mut from_zeros = ExampleField::zeros();
assert_eq!("00000000", from_zeros.as_binary());

// set bit to 1
from_zeros |= ExampleFlags::Flag1;
assert_eq!("00000010", from_zeros.as_binary());

// set bit back to 0
from_zeros &= ExampleFlags::Flag1;
assert_eq!("00000000", from_zeros.as_binary());

// toggle a bit
from_zeros ^= ExampleFlags::Flag1;
assert_eq!("00000010", from_zeros.as_binary());

from_zeros ^= ExampleFlags::Flag1;
assert_eq!("00000000", from_zeros.as_binary());

Operations can also be chained together:


let mut from_zeros = ExampleField::zeros() | ExampleFlags::Flag1 | ExampleFlags::Flag3;
assert_eq!("00001010", from_zeros.as_binary());

Bitfield instances can also be created from combining flags:


let mut from_zeros = ExampleFlags::Flag1 | ExampleFlags::Flag3;
assert_eq!("00001010", from_zeros.as_binary());

Fields named with flags

The generated flags enum allows you to access bits by name. The flag has an associated u8 value, which determines the index its target bit. (See bitfield for more info)

With the following input…

1 0 1 0 0 1 1 0

and the following flags…

0 : f1
1 : f1
2 : f2
3 : f3
4 : f4
5 : f5
6 : f6
7 : f7

we end up with this layout.

namef7f6f5f4f3f2f1f0
bit value10100110
index76543210

With the same input and only the first few flags:

0 : f0
1 : f1
2 : f2

we end up with this layout.

namef2f1f0
bit value10100110
index76543210

Using the same input, but with dispersed flags:

1 : f0
3 : f1
6 : f2

we end up with this layout.

namef2f1f0
bit value10100110
index76543210

Modules

Examples of generated output using different configurations.

Macros

Generates a bitfield struct and a corresponding flag enum.