slicefields 1.0.4

Allows for data structures whose members are sub byte aligned (e.g. a one bit alignment)
Documentation
use slicefields::slicefields;

#[test]
fn getter_simple() {
    #[slicefields(first_byte(u8,bits(0..8)))]
    struct B1t {
        pub bits: u32,
        _blobs: u64,
    }
    let bit = B1t {
        bits: 0b11111111_10110111,
        _blobs: 1337,
    };
    assert_eq!(bit.first_byte(), 0b10110111);
}

#[test]
fn syntax_parser() {
    #[slicefields(first_byte(u8,bits(0..4),bits(4..8)),second_byte(u8,bits(8..16)))]
    struct B1t {
        pub bits: u32,
        _blobs: u64,
    }
    let bit = B1t {
        bits: 0b11111111_10110111,
        _blobs: 1337,
    };
    assert_eq!(bit.first_byte(), 0b10110111);
    assert_eq!(bit.second_byte(), 0b11111111);
}

// this test should never fail but it'd be a shame if we accidentally did manage to break
// it, for example if the proc macro api changed
#[test]
fn syntax_parser_whitespace() {
    #[slicefields(
        first_byte(u8, bits(0..4), bits(4..8)),
        second_byte(u8, bits(8..16))
    )]
    struct B1t {
        pub bits: u32,
        _blobs: u64,
    }
    let bit = B1t {
        bits: 0b11111111_10110111,
        _blobs: 1337,
    };
    assert_eq!(bit.first_byte(), 0b10110111);
    assert_eq!(bit.second_byte(), 0b11111111);
}

#[test]
fn getter_bitflag() {
    #[slicefields(
        is_cat(bool, bits(0..1))
    )]
    struct B1t {
        pub bits: u32,
        _blobs: u64,
    }
    let bit = B1t {
        bits: 00000000_00000001,
        _blobs: 1337,
    };
    assert_eq!(bit.is_cat(), true);
}

#[test]
fn setter_simple() {
    #[slicefields(first_byte(u8,bits(0..8)))]
    struct B1t {
        pub bits: u32,
        _blobs: u64,
    }
    let mut bit = B1t {
        bits: 00000000_00000000,
        _blobs: 1337,
    };
    bit.set_first_byte(0b10110111);
    assert_eq!(bit.first_byte(), 0b10110111);
}

#[test]
fn setter_bitflag() {
    #[slicefields(
        is_cat(bool, bits(0..1))
    )]
    struct B1t {
        pub bits: u32,
        _blobs: u64,
    }
    let mut bit = B1t {
        bits: 00000000_00000000,
        _blobs: 1337,
    };
    bit.set_is_cat(true);
    assert_eq!(bit.is_cat(), true);
}

#[test]
fn example_tss_segment() {
    #[slicefields(
        limit(u16, lower(0..16)),
        base(u64,
            lower(16..40),
            lower(56..64),
            higher(0..32)
        ),
        r#type(u8, lower(40..44)),
        present(bool, lower(47..48))
    )]
    struct TssDescriptor {
        lower: u64,
        higher: u32,
    }
    let mut tss = TssDescriptor {
        lower: 0,
        higher: 0,
    };
    tss.set_base(0xDEADBEEF);
    tss.set_present(true);
    assert_eq!(tss.present(), true);
    assert_eq!(tss.base(), 0xDEADBEEF);
}


#[test]
fn example_lvt_register() {
    #[slicefields(
        vector(u8, value(0..8)),
        pending(bool, value(12..13)),
        mask(bool, value(16..17)),
        mode(u8, value(17..19))
    )]
    #[repr(C)]
    struct TimerRegister {
        value: u32,
        _align_1: u32,
        _align_2: u32,
    }
}

#[test]
fn options() {
    #[slicefields((unaligned)
        vector(u8, value(0..8)),
        pending(bool, value(12..13)),
        mask(bool, value(17..17)),
        mode(u8, value(17..19))
    )]
    #[repr(C, packed)]
    struct TimerRegister {
        value: u32,
        _align_1: u64,
        _align_2: u32,
    }
}

#[test]
fn boolean() {
    #[slicefields(
        truth(bool, value(1..2)),
        truth8(u8, value(1..2)),
    )]
    #[repr(C, packed)]
    struct BooleanGetter {
        value: u32,
    }
    let mut x = BooleanGetter {
        value: 2,
    };
    assert_eq!(x.truth8(), 1);
    assert!(x.truth());
    x.set_truth(false);
    assert_eq!(x.truth8(), 0);
}

#[test]
fn boolean_other() {
    #[slicefields(
        truth(bool, value(16..17)),
    )]
    #[repr(C)]
    struct BooleanGetter {
        pub value: u32,
    }
    let mut x = BooleanGetter {
        value: 1 << 16,
    };
    assert!(x.truth());
    x.value = 0;
    assert!(!x.truth());
    x.set_truth(true);
    assert_eq!(x.value, 1 << 16);
}