userspace/macros/enums/
opted.rs1#[macro_export]
2macro_rules! enum_opted {
3 ($enum_vis:vis $enum_identifier:ident, $enum_discriminant_type:ty, [$([$variant_discriminant:expr,$variant_identifier:ident,$variant_type:ty]),* $(,)? ]) => {
4 #[derive(Debug, Clone, Copy)]
5 $enum_vis enum $enum_identifier {
6 $($variant_identifier($variant_type)),*
7 }
8
9 impl $enum_identifier {
10 pub fn discriminant(&self) -> $enum_discriminant_type {
11 match self {
12 $($enum_identifier::$variant_identifier(_) => $variant_discriminant),*
13 }
14 }
15 }
16
17 impl traits::Bytes<crate::Origin,crate::Origin> for $enum_identifier {
18 const BYTES_SIZE : usize = <$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE + expressions_upperbound!($(<Option<$variant_type> as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE),*);
19 fn to_bytes(&self, endianness: bool) -> [u8;Self::BYTES_SIZE] {
20 let mut bytes = [0u8;Self::BYTES_SIZE];
21
22 match self {
23 $(
24 Self::$variant_identifier(payload) => {
25 let discriminant = self.discriminant();
26
27 let mut o = 0;
28 bytes[o..(o+<$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE)].copy_from_slice(
29 &if endianness {
30 <$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::to_le_bytes(&discriminant)
31 } else {
32 <$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::to_be_bytes(&discriminant)
33 }
34 );
35 o = o + <$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
36 bytes[o..(o+<$variant_type as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE)].copy_from_slice(
37 &if endianness {
38 <$variant_type as traits::Bytes<crate::Origin,crate::Origin>>::to_le_bytes(payload)
39 } else {
40 <$variant_type as traits::Bytes<crate::Origin,crate::Origin>>::to_be_bytes(payload)
41 }
42 );
43 bytes
44 }
45 ),*
46 }
47 }
48
49 fn from_bytes(bytes: [u8;Self::BYTES_SIZE], endianness: bool) -> Self {
50 let mut o = 0;
51 let mut discriminant_bytes = [0u8; <$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE];
52 discriminant_bytes.copy_from_slice(&bytes[o..(o+<$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE)]);
53 let discriminant = if endianness {
54 <$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::from_le_bytes(discriminant_bytes)
55 } else {
56 <$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::from_be_bytes(discriminant_bytes)
57 };
58 o = o + <$enum_discriminant_type as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE;
59 match discriminant {
60 $(
61 $variant_discriminant => {
62 Self::$variant_identifier({
63 let mut payload = [0u8; <$variant_type as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE];
64 payload.copy_from_slice(&bytes[o..(o+<$variant_type as traits::Bytes<crate::Origin,crate::Origin>>::BYTES_SIZE)]);
65 if endianness {
66 <$variant_type as traits::Bytes<crate::Origin,crate::Origin>>::from_le_bytes(payload)
67 } else {
68 <$variant_type as traits::Bytes<crate::Origin,crate::Origin>>::from_be_bytes(payload)
69 }
70 })
71 },
72 )*
73 _ => unreachable!()
74 }
75
76 }
77 }
78 };
79}
80pub use enum_opted;