123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- use const_serialize::{deserialize_const, serialize_const, ConstVec, SerializeConst};
- use std::mem::MaybeUninit;
- #[test]
- fn test_transmute_bytes_to_enum() {
- #[derive(Clone, Copy, Debug, PartialEq)]
- #[repr(C, u8)]
- enum Enum<T> {
- A { one: u32, two: u16 },
- B { one: u8, two: T } = 15,
- }
- #[repr(C)]
- #[derive(Debug, PartialEq)]
- struct A {
- one: u32,
- two: u16,
- }
- #[repr(C)]
- #[derive(Debug, PartialEq)]
- struct B<T> {
- one: u8,
- two: T,
- }
- const SIZE: usize = std::mem::size_of::<Enum<u16>>();
- let mut out = [MaybeUninit::uninit(); SIZE];
- let discriminate_size = std::mem::size_of::<u8>();
- let tag_align = 0;
- let union_alignment = std::mem::align_of::<A>().max(std::mem::align_of::<B<u16>>());
- let data_align = (discriminate_size / union_alignment) + union_alignment;
- let a_one_align = std::mem::offset_of!(A, one);
- let a_two_align = std::mem::offset_of!(A, two);
- let b_one_align = std::mem::offset_of!(B<u16>, one);
- let b_two_align = std::mem::offset_of!(B<u16>, two);
- let one = 1234u32;
- let two = 5678u16;
- let first = Enum::A { one, two };
- for (i, byte) in one.to_le_bytes().iter().enumerate() {
- out[data_align + i + a_one_align] = MaybeUninit::new(*byte);
- }
- for (i, byte) in two.to_le_bytes().iter().enumerate() {
- out[data_align + i + a_two_align] = MaybeUninit::new(*byte);
- }
- out[tag_align] = MaybeUninit::new(0);
- let out = unsafe { std::mem::transmute_copy::<[MaybeUninit<u8>; SIZE], Enum<u16>>(&out) };
- assert_eq!(out, first);
- let mut out = [MaybeUninit::uninit(); SIZE];
- let one = 123u8;
- let two = 58u16;
- let second = Enum::B { one, two };
- for (i, byte) in one.to_le_bytes().iter().enumerate() {
- out[data_align + i + b_one_align] = MaybeUninit::new(*byte);
- }
- for (i, byte) in two.to_le_bytes().iter().enumerate() {
- out[data_align + i + b_two_align] = MaybeUninit::new(*byte);
- }
- out[tag_align] = MaybeUninit::new(15);
- let out = unsafe { std::mem::transmute_copy::<[MaybeUninit<u8>; SIZE], Enum<u16>>(&out) };
- assert_eq!(out, second);
- }
- #[test]
- fn test_serialize_enum() {
- #[derive(Clone, Copy, Debug, PartialEq, SerializeConst)]
- #[repr(C, u8)]
- enum Enum {
- A { one: u32, two: u16 },
- B { one: u8, two: u16 } = 15,
- }
- println!("{:#?}", Enum::MEMORY_LAYOUT);
- let data = Enum::A {
- one: 0x11111111,
- two: 0x22,
- };
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!(Enum, buf).unwrap().1, data);
- let data = Enum::B {
- one: 0x11,
- two: 0x2233,
- };
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!(Enum, buf).unwrap().1, data);
- }
- #[test]
- fn test_serialize_list_of_lopsided_enums() {
- #[derive(Clone, Copy, Debug, PartialEq, SerializeConst)]
- #[repr(C, u8)]
- enum Enum {
- A,
- B { one: u8, two: u16 } = 15,
- }
- println!("{:#?}", Enum::MEMORY_LAYOUT);
- let data = [Enum::A, Enum::A];
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!([Enum; 2], buf).unwrap().1, data);
- let data = [
- Enum::B {
- one: 0x11,
- two: 0x2233,
- },
- Enum::B {
- one: 0x12,
- two: 0x2244,
- },
- ];
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!([Enum; 2], buf).unwrap().1, data);
- let data = [
- Enum::A,
- Enum::B {
- one: 0x11,
- two: 0x2233,
- },
- ];
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!([Enum; 2], buf).unwrap().1, data);
- let data = [
- Enum::B {
- one: 0x11,
- two: 0x2233,
- },
- Enum::A,
- ];
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!([Enum; 2], buf).unwrap().1, data);
- }
- #[test]
- fn test_serialize_u8_enum() {
- #[derive(Clone, Copy, Debug, PartialEq, SerializeConst)]
- #[repr(u8)]
- enum Enum {
- A,
- B,
- }
- println!("{:#?}", Enum::MEMORY_LAYOUT);
- let data = Enum::A;
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!(Enum, buf).unwrap().1, data);
- let data = Enum::B;
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!(Enum, buf).unwrap().1, data);
- }
- #[test]
- fn test_serialize_corrupted_enum() {
- #[derive(Clone, Copy, Debug, PartialEq, SerializeConst)]
- #[repr(C, u8)]
- enum Enum {
- A { one: u32, two: u16 },
- }
- let data = Enum::A {
- one: 0x11111111,
- two: 0x22,
- };
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- buf = buf.set(0, 2);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!(Enum, buf), None);
- }
- #[test]
- fn test_serialize_nested_enum() {
- #[derive(Clone, Copy, Debug, PartialEq, SerializeConst)]
- #[repr(C, u8)]
- enum Enum {
- A { one: u32, two: u16 },
- B { one: u8, two: InnerEnum } = 15,
- }
- #[derive(Clone, Copy, Debug, PartialEq, SerializeConst)]
- #[repr(C, u16)]
- enum InnerEnum {
- A(u8),
- B { one: u64, two: f64 } = 1000,
- C { one: u32, two: u16 },
- }
- let data = Enum::A {
- one: 0x11111111,
- two: 0x22,
- };
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!(Enum, buf).unwrap().1, data);
- let data = Enum::B {
- one: 0x11,
- two: InnerEnum::A(0x22),
- };
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!(Enum, buf).unwrap().1, data);
- let data = Enum::B {
- one: 0x11,
- two: InnerEnum::B {
- one: 0x2233,
- two: 0.123456789,
- },
- };
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!(Enum, buf).unwrap().1, data);
- let data = Enum::B {
- one: 0x11,
- two: InnerEnum::C {
- one: 0x2233,
- two: 56789,
- },
- };
- let mut buf = ConstVec::new();
- buf = serialize_const(&data, buf);
- println!("{:?}", buf.as_ref());
- let buf = buf.read();
- assert_eq!(deserialize_const!(Enum, buf).unwrap().1, data);
- }
|