esp_hal/
macros.rs

1//! Macros used by the HAL.
2//!
3//! Most of the macros in this module are hidden and intended for internal use
4//! only. For the list of public macros, see the [procmacros](https://docs.rs/esp-hal-procmacros/latest/esp_hal_procmacros/)
5//! documentation.
6#[doc(hidden)]
7/// Helper macro for checking doctest code snippets
8#[macro_export]
9macro_rules! before_snippet {
10    () => {
11        r#"
12# #![no_std]
13# use procmacros::handler;
14# use esp_hal::{interrupt::{self, InterruptConfigurable}, time::{Duration, Instant, Rate}};
15# macro_rules! println {
16#     ($($tt:tt)*) => { };
17# }
18# macro_rules! print {
19#     ($($tt:tt)*) => { };
20# }
21# #[panic_handler]
22# fn panic(_ : &core::panic::PanicInfo) -> ! {
23#     loop {}
24# }
25# fn main() {
26#   let _ = example();
27# }
28# struct ExampleError {}
29# impl <T> From<T> for ExampleError where T: core::fmt::Debug {
30#   fn from(_value: T) -> Self {
31#       Self{}
32#   }
33# }
34# fn example() -> Result<(), ExampleError> {
35#   let mut peripherals = esp_hal::init(esp_hal::Config::default());
36"#
37    };
38}
39
40#[doc(hidden)]
41#[macro_export]
42macro_rules! trm_markdown_link {
43    () => {
44        concat!("[Technical Reference Manual](", $crate::trm_link!(), ")")
45    };
46    ($anchor:literal) => {
47        concat!(
48            "[Technical Reference Manual](",
49            $crate::trm_link!(),
50            "#",
51            $anchor,
52            ")"
53        )
54    };
55}
56
57#[doc(hidden)]
58/// Shorthand to define enums with From implementations.
59#[macro_export]
60macro_rules! any_enum {
61    ($(#[$meta:meta])* $vis:vis enum $name:ident {
62        $(
63            $(#[$variant_meta:meta])*
64            $variant:ident($inner:ty)
65        ),* $(,)?
66    }) => {
67        $(#[$meta])*
68        $vis enum $name {
69            $(
70                $(#[$variant_meta])*
71                $variant($inner),
72            )*
73        }
74
75        $(
76            $(#[$variant_meta])*
77            impl From<$inner> for $name {
78                fn from(inner: $inner) -> Self {
79                    $name::$variant(inner)
80                }
81            }
82        )*
83    };
84}
85
86#[doc(hidden)]
87/// Shorthand to define AnyPeripheral instances.
88#[macro_export]
89macro_rules! any_peripheral {
90    ($(#[$meta:meta])* $vis:vis peripheral $name:ident {
91        $(
92            $(#[cfg($variant_meta:meta)])*
93            $variant:ident($inner:ty)
94        ),* $(,)?
95    }) => {
96        paste::paste! {
97            $(#[$meta])*
98            #[derive(Debug)]
99            #[cfg_attr(feature = "defmt", derive(defmt::Format))]
100            $vis struct $name([< $name Inner >]);
101            impl $crate::private::Sealed for $name {}
102
103            impl $crate::peripheral::Peripheral for $name {
104                type P = $name;
105
106                unsafe fn clone_unchecked(&self) -> Self::P {
107                    match &self.0 {
108                        $(
109                            $(#[cfg($variant_meta)])*
110                            [<$name Inner>]::$variant(inner) => $name::from(inner.clone_unchecked()),
111                        )*
112                    }
113                }
114            }
115
116            $(#[$meta])*
117            #[derive(Debug)]
118            enum [< $name Inner >] {
119                $(
120                    $(#[cfg($variant_meta)])*
121                    $variant($inner),
122                )*
123            }
124
125            #[cfg(feature = "defmt")]
126            impl defmt::Format for [< $name Inner >] {
127                fn format(&self, fmt: defmt::Formatter<'_>) {
128                    match self {
129                        $(
130                            $(#[cfg($variant_meta)])*
131                            [< $name Inner >]::$variant(inner) => inner.format(fmt),
132                        )*
133                    }
134                }
135            }
136
137            $(
138                $(#[cfg($variant_meta)])*
139                impl From<$inner> for $name {
140                    fn from(inner: $inner) -> Self {
141                        Self([< $name Inner >]::$variant(inner))
142                    }
143                }
144            )*
145        }
146    };
147}
148
149/// Macro to choose between two expressions. Useful for implementing "else" for
150/// `$()?` macro syntax.
151#[macro_export]
152#[doc(hidden)]
153macro_rules! if_set {
154    (, $not_set:expr) => {
155        $not_set
156    };
157    ($set:expr, $not_set:expr) => {
158        $set
159    };
160}
161
162/// Macro to ignore tokens.
163///
164/// This is useful when we need existence of a metavariable (to expand a
165/// repetition), but we don't need to use it.
166#[macro_export]
167#[doc(hidden)]
168macro_rules! ignore {
169    ($($item:tt)*) => {};
170}