userspace/macros/enums/labeled.rs
1/// A macro that defines an error type and error handling for syscalls.
2///
3/// This macro generates:
4/// 1. An Error enum with the specified variants and their associated discriminant values
5/// 2. ErrorTrait implementation for the Error type with proper discriminant mapping
6/// 3. An discriminant module with standard Linux error constants
7/// 4. Into<isize> implementation for the Error type
8/// 5. A handle_result function that maps arch errors to syscall errors
9///
10/// # Arguments
11///
12/// * `$enum_identifier` - The name of the error enum (usually Error)
13/// * `$variant` - The variant name in the crate::result::Error enum (e.g., Open, Read, Write)
14/// * `$enum_label` - String slice with the syscall name
15/// * A list of error variants with their descriptions, discriminant values and Linux standard constant names
16/// [VariantName, discriminant_value, "description", "LINUX_CONSTANT"]
17///
18/// # Example
19///
20/// ```
21/// $enum_identifier:ident,
22/// $variant:ty,
23/// $enum_label:expr,
24/// [
25/// $(
26/// [
27/// $variant_discriminant:expr;
28/// $variant_identifier:ident;
29/// $variant_const_identifier:ident;
30/// $variant_acronym:expr;
31/// $variant_description:expr
32/// ]
33/// ),* $(,)?
34/// ]
35/// ```
36#[macro_export]
37#[rustfmt::skip]
38macro_rules! enum_labeled {
39 (
40 $enum_vis:vis $enum_identifier:ident,
41 $enum_discriminant_type:ty,
42 $enum_label:expr,
43 [
44 $(
45 [
46 $variant_discriminant:expr;
47 $variant_identifier:ident;
48 $variant_type:ty;
49 $variant_const_identifier:ident;
50 $variant_acronym:expr;
51 $variant_description:expr
52 ]
53 ),* $(,)?
54 ]
55 ) => {
56
57 r#enum!(
58 $enum_vis $enum_identifier,
59 $enum_discriminant_type, [
60 $(
61 [$variant_discriminant, $variant_identifier, $variant_type]
62 ),*
63 ]);
64
65 pub mod constants {
66 $(
67 pub const $variant_const_identifier: $enum_discriminant_type = $variant_discriminant;
68 )*
69 }
70
71 impl crate::traits::enums::Labeled<crate::Origin> for $enum_identifier {
72 fn description(&self) -> &str {
73 match self {
74 $(Self::$variant_identifier(_) => $variant_description,)*
75 }
76 }
77
78 fn acronym(&self) -> &str {
79 match *self {
80 $(Self::$variant_identifier(_) => $variant_acronym,)*
81 }
82 }
83 }
84
85 // impl core::ops::Add for $enum_identifier {
86 // type Output = Self;
87
88 // fn add(self, rhs: Self) -> Self::Output {
89 // $enum_identifier::from(self.discriminant() | rhs.discriminant())
90 // }
91 // }
92
93 // impl core::ops::Sub for $enum_identifier {
94 // type Output = Self;
95
96 // fn sub(self, rhs: Self) -> Self::Output {
97 // $enum_identifier::from(self.discriminant() & !rhs.discriminant())
98 // }
99 // }
100
101 impl core::fmt::Display for $enum_identifier {
102 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
103 use crate::traits::enums::Labeled;
104 write!(f, "{}:{}",self.discriminant(), self.description())
105 }
106 }
107
108 // impl core::fmt::Debug for $enum_identifier {
109 // fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
110 // write!(f, "{}:{}",self.discriminant(), self.acronym())
111 // }
112 // }
113 };
114}
115pub use enum_labeled;