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;