Expand description
This crate exposes the bit_parity macro to enforce a given bit parity
§Motivation
Without bit parity, erroneous/random bit flips can lead to unexpected behavior.
§Without Bit Parity
use enum_parity::bit_parity;
use serde_repr::{Serialize_repr, Deserialize_repr};
#[repr(u8)]
// `serialize_repr` must be used, because `serde` uses enum indexes for binary serializations
#[derive(Serialize_repr, Deserialize_repr)]
enum Foo { A, B, C, D }
let val = Foo::A;
let mut serialized_val = postcard::to_allocvec(&val).unwrap();
// *Random bit flip*
serialized_val[0] |= 0x01;
// This successfully deserializes, but is the incorrect value!
let new_val: Foo = postcard::from_bytes(&serialized_val).unwrap();
assert_eq!(new_val, Foo::B);
assert_ne!(val, new_val);§With Bit Parity
#[repr(u8)]
#[bit_parity(even)] // using bit parity!
#[derive(Serialize_repr, Deserialize_repr)]
enum Foo { A, B, C, D }
let val = Foo::A;
let mut serialized_val = postcard::to_allocvec(&val).unwrap();
// *Random bit flip*
serialized_val[0] |= 0x01;
// This fails to deserialize
let new_par_err: postcard::Result<Foo> = postcard::from_bytes(&serialized_val);
assert_eq!(new_par_err, Err(postcard::Error::SerdeDeCustom));§Examples
§Even Bit Parity
use enum_parity::bit_parity;
#[repr(u8)]
#[bit_parity(even)]
pub enum EvenSample {
Foo,
Bar,
Baz,
Quo,
}
assert_eq!(EvenSample::Foo as u8, 0x00);
assert_eq!(EvenSample::Bar as u8, 0x03);
assert_eq!(EvenSample::Baz as u8, 0x05);
assert_eq!(EvenSample::Quo as u8, 0x06);§Odd Bit Parity
use enum_parity::bit_parity;
#[repr(u8)]
#[bit_parity(odd)]
pub enum OddSample {
Lorem,
Ipsum,
Dolor,
Sit,
}
assert_eq!(OddSample::Lorem as u8, 0x01);
assert_eq!(OddSample::Ipsum as u8, 0x02);
assert_eq!(OddSample::Dolor as u8, 0x04);
assert_eq!(OddSample::Sit as u8, 0x07);Attribute Macros§
- bit_
parity - An attribute macro for enums that enforces discriminant bit parity