C-like packed bitfield-struct in Rust

I have a binary packet format, and I want to parse it.
In C language I write a packed struct, for example: Compiler Explorer

Is there the same struct type in (unsafe) Rust?

No, you would have to use your own bit manipulation to get this.

1 Like

I recently found out that bindgen will write this for you if you give it the c header. ( I changed the uint8_t type into int as I didn't have the include header )

Here's the output of your _status

impl _status {
    #[inline]
    pub fn dooropen(&self) -> ::std::os::raw::c_int {
        unsafe {
            ::std::mem::transmute(
                self._bitfield_1
                    .get(0usize, 1u8) as u32,
            )
        }
    }
    #[inline]
    pub fn set_dooropen(&mut self, val: ::std::os::raw::c_int) {
        unsafe {
            let val: u32 = ::std::mem::transmute(val);
            self._bitfield_1
                .set(0usize, 1u8, val as u64)
        }
    }
    #[inline]
    pub fn err230(&self) -> ::std::os::raw::c_int {
        unsafe {
            ::std::mem::transmute(
                self._bitfield_1
                    .get(1usize, 1u8) as u32,
            )
        }
    }
    #[inline]
    pub fn set_err230(&mut self, val: ::std::os::raw::c_int) {
        unsafe {
            let val: u32 = ::std::mem::transmute(val);
            self._bitfield_1
                .set(1usize, 1u8, val as u64)
        }
    }
    #[inline]
    pub fn errpsu(&self) -> ::std::os::raw::c_int {
        unsafe {
            ::std::mem::transmute(
                self._bitfield_1
                    .get(2usize, 1u8) as u32,
            )
        }
    }
    #[inline]
    pub fn set_errpsu(&mut self, val: ::std::os::raw::c_int) {
        unsafe {
            let val: u32 = ::std::mem::transmute(val);
            self._bitfield_1
                .set(2usize, 1u8, val as u64)
        }
    }
    #[inline]
    pub fn errbatt(&self) -> ::std::os::raw::c_int {
        unsafe {
            ::std::mem::transmute(
                self._bitfield_1
                    .get(3usize, 1u8) as u32,
            )
        }
    }
    #[inline]
    pub fn set_errbatt(&mut self, val: ::std::os::raw::c_int) {
        unsafe {
            let val: u32 = ::std::mem::transmute(val);
            self._bitfield_1
                .set(3usize, 1u8, val as u64)
        }
    }
    #[inline]
    pub fn errpwrct(&self) -> ::std::os::raw::c_int {
        unsafe {
            ::std::mem::transmute(
                self._bitfield_1
                    .get(4usize, 4u8) as u32,
            )
        }
    }
    #[inline]
    pub fn set_errpwrct(&mut self, val: ::std::os::raw::c_int) {
        unsafe {
            let val: u32 = ::std::mem::transmute(val);
            self._bitfield_1
                .set(4usize, 4u8, val as u64)
        }
    }
    #[inline]
    pub fn errcomm(&self) -> ::std::os::raw::c_int {
        unsafe {
            ::std::mem::transmute(
                self._bitfield_1
                    .get(8usize, 4u8) as u32,
            )
        }
    }
    #[inline]
    pub fn set_errcomm(&mut self, val: ::std::os::raw::c_int) {
        unsafe {
            let val: u32 = ::std::mem::transmute(val);
            self._bitfield_1
                .set(8usize, 4u8, val as u64)
        }
    }
    #[inline]
    pub fn errmeas(&self) -> ::std::os::raw::c_int {
        unsafe {
            ::std::mem::transmute(
                self._bitfield_1
                    .get(12usize, 2u8) as u32,
            )
        }
    }
    #[inline]
    pub fn set_errmeas(&mut self, val: ::std::os::raw::c_int) {
        unsafe {
            let val: u32 = ::std::mem::transmute(val);
            self._bitfield_1
                .set(12usize, 2u8, val as u64)
        }
    }
    #[inline]
    pub fn sparebit(&self) -> ::std::os::raw::c_int {
        unsafe {
            ::std::mem::transmute(
                self._bitfield_1
                    .get(14usize, 2u8) as u32,
            )
        }
    }
    #[inline]
    pub fn set_sparebit(&mut self, val: ::std::os::raw::c_int) {
        unsafe {
            let val: u32 = ::std::mem::transmute(val);
            self._bitfield_1
                .set(14usize, 2u8, val as u64)
        }
    }
    #[inline]
    pub fn new_bitfield_1(
        dooropen: ::std::os::raw::c_int,
        err230: ::std::os::raw::c_int,
        errpsu: ::std::os::raw::c_int,
        errbatt: ::std::os::raw::c_int,
        errpwrct: ::std::os::raw::c_int,
        errcomm: ::std::os::raw::c_int,
        errmeas: ::std::os::raw::c_int,
        sparebit: ::std::os::raw::c_int,
    ) -> __BindgenBitfieldUnit<[u8; 2usize]> {
        let mut __bindgen_bitfield_unit: __BindgenBitfieldUnit<[u8; 2usize]> = Default::default();
        __bindgen_bitfield_unit.set(0usize, 1u8, {
            let dooropen: u32 = unsafe { ::std::mem::transmute(dooropen) };
            dooropen as u64
        });
        __bindgen_bitfield_unit.set(1usize, 1u8, {
            let err230: u32 = unsafe { ::std::mem::transmute(err230) };
            err230 as u64
        });
        __bindgen_bitfield_unit.set(2usize, 1u8, {
            let errpsu: u32 = unsafe { ::std::mem::transmute(errpsu) };
            errpsu as u64
        });
        __bindgen_bitfield_unit.set(3usize, 1u8, {
            let errbatt: u32 = unsafe { ::std::mem::transmute(errbatt) };
            errbatt as u64
        });
        __bindgen_bitfield_unit.set(4usize, 4u8, {
            let errpwrct: u32 = unsafe { ::std::mem::transmute(errpwrct) };
            errpwrct as u64
        });
        __bindgen_bitfield_unit.set(8usize, 4u8, {
            let errcomm: u32 = unsafe { ::std::mem::transmute(errcomm) };
            errcomm as u64
        });
        __bindgen_bitfield_unit.set(12usize, 2u8, {
            let errmeas: u32 = unsafe { ::std::mem::transmute(errmeas) };
            errmeas as u64
        });
        __bindgen_bitfield_unit.set(14usize, 2u8, {
            let sparebit: u32 = unsafe { ::std::mem::transmute(sparebit) };
            sparebit as u64
        });
        __bindgen_bitfield_unit
    }
}

You may also be interested in bitfield — Rust library // Lib.rs or modular-bitfield — Rust utility // Lib.rs

1 Like