1macro_rules! cfg_if {
10 ($(
12 if #[cfg($($meta:meta),*)] { $($it:item)* }
13 ) else * else {
14 $($it2:item)*
15 }) => {
16 cfg_if! {
17 @__items
18 () ;
19 $( ( ($($meta),*) ($($it)*) ), )*
20 ( () ($($it2)*) ),
21 }
22 };
23
24 (
26 if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
27 $(
28 else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
29 )*
30 ) => {
31 cfg_if! {
32 @__items
33 () ;
34 ( ($($i_met),*) ($($i_it)*) ),
35 $( ( ($($e_met),*) ($($e_it)*) ), )*
36 ( () () ),
37 }
38 };
39
40 (@__items ($($not:meta,)*) ; ) => {};
45 (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ),
46 $($rest:tt)*) => {
47 cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
51
52 cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
56 };
57
58 (@__apply $m:meta, $($it:item)*) => {
60 $(#[$m] $it)*
61 };
62}
63
64macro_rules! prelude {
66 () => {
67 mod types;
68
69 mod prelude {
73 #[allow(unused_imports)]
75 pub(crate) use core::clone::Clone;
76 #[allow(unused_imports)]
77 pub(crate) use core::default::Default;
78 #[allow(unused_imports)]
79 pub(crate) use core::marker::{Copy, Send, Sync};
80 #[allow(unused_imports)]
81 pub(crate) use core::option::Option;
82 #[allow(unused_imports)]
83 pub(crate) use core::prelude::v1::derive;
84 #[allow(unused_imports)]
85 pub(crate) use core::{fmt, hash, iter, mem, ptr};
86
87 #[allow(unused_imports)]
88 pub(crate) use fmt::Debug;
89 #[allow(unused_imports)]
90 pub(crate) use mem::{align_of, align_of_val, size_of, size_of_val};
91
92 #[allow(unused_imports)]
93 pub(crate) use crate::types::{CEnumRepr, Padding};
94 #[allow(unused_imports)]
96 pub(crate) use crate::{
97 c_char, c_double, c_float, c_int, c_long, c_longlong, c_short, c_uchar, c_uint,
98 c_ulong, c_ulonglong, c_ushort, c_void, intptr_t, size_t, ssize_t, uintptr_t,
99 };
100 }
101 };
102}
103
104macro_rules! s {
110 ($(
111 $(#[$attr:meta])*
112 pub $t:ident $i:ident { $($field:tt)* }
113 )*) => ($(
114 s!(it: $(#[$attr])* pub $t $i { $($field)* });
115 )*);
116
117 (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => (
118 compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
119 );
120
121 (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => (
122 __item! {
123 #[repr(C)]
124 #[cfg_attr(
125 feature = "extra_traits",
126 ::core::prelude::v1::derive(Eq, Hash, PartialEq)
127 )]
128 #[::core::prelude::v1::derive(
129 ::core::clone::Clone,
130 ::core::marker::Copy,
131 ::core::fmt::Debug,
132 )]
133 #[allow(deprecated)]
134 $(#[$attr])*
135 pub struct $i { $($field)* }
136 }
137 );
138}
139
140macro_rules! s_paren {
145 ($(
146 $(#[$attr:meta])*
147 pub struct $i:ident ( $($field:tt)* );
148 )*) => ($(
149 __item! {
150 #[cfg_attr(
151 feature = "extra_traits",
152 ::core::prelude::v1::derive(Eq, Hash, PartialEq)
153 )]
154 #[::core::prelude::v1::derive(
155 ::core::clone::Clone,
156 ::core::marker::Copy,
157 ::core::fmt::Debug,
158 )]
159 $(#[$attr])*
160 pub struct $i ( $($field)* );
161 }
162 )*);
163}
164
165macro_rules! s_no_extra_traits {
170 ($(
171 $(#[$attr:meta])*
172 pub $t:ident $i:ident { $($field:tt)* }
173 )*) => ($(
174 s_no_extra_traits!(it: $(#[$attr])* pub $t $i { $($field)* });
175 )*);
176
177 (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => (
178 __item! {
179 #[repr(C)]
180 #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)]
181 $(#[$attr])*
182 pub union $i { $($field)* }
183 }
184
185 impl ::core::fmt::Debug for $i {
186 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
187 f.debug_struct(::core::stringify!($i)).finish_non_exhaustive()
188 }
189 }
190 );
191
192 (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => (
193 __item! {
194 #[repr(C)]
195 #[::core::prelude::v1::derive(
196 ::core::clone::Clone,
197 ::core::marker::Copy,
198 ::core::fmt::Debug,
199 )]
200 $(#[$attr])*
201 pub struct $i { $($field)* }
202 }
203 );
204}
205
206macro_rules! missing {
209 ($(
210 $(#[$attr:meta])*
211 pub enum $i:ident {}
212 )*) => ($(
213 $(#[$attr])*
214 #[allow(missing_copy_implementations)]
215 pub enum $i { }
216 )*);
217}
218
219macro_rules! e {
223 ($(
224 $(#[$attr:meta])*
225 pub enum $i:ident { $($field:tt)* }
226 )*) => ($(
227 __item! {
228 #[cfg_attr(
229 feature = "extra_traits",
230 ::core::prelude::v1::derive(Eq, Hash, PartialEq)
231 )]
232 #[::core::prelude::v1::derive(
233 ::core::clone::Clone,
234 ::core::marker::Copy,
235 ::core::fmt::Debug,
236 )]
237 $(#[$attr])*
238 pub enum $i { $($field)* }
239 }
240 )*);
241}
242
243macro_rules! c_enum {
251 ($(
252 $(#[repr($repr:ty)])?
253 pub enum $ty_name:ident {
254 $($variant:ident $(= $value:expr)?,)+
255 }
256 )+) => {
257 $(c_enum!(@expand;
258 $(#[repr($repr)])?
259 pub enum $ty_name {
260 $($variant $(= $value)?,)+
261 }
262 );)+
263 };
264
265 (@expand;
266 $(#[repr($repr:ty)])?
267 pub enum $ty_name:ident {
268 $($variant:ident $(= $value:expr)?,)+
269 }
270 ) => {
271 pub type $ty_name = c_enum!(@ty $($repr)?);
272 c_enum!(@one; $ty_name; 0; $($variant $(= $value)?,)+);
273 };
274
275 (@one; $_ty_name:ident; $_idx:expr;) => {};
277 (
278 @one; $ty_name:ident; $default_val:expr;
279 $variant:ident $(= $value:expr)?,
280 $($tail:tt)*
281 ) => {
282 pub const $variant: $ty_name = {
283 #[allow(unused_variables)]
284 let r = $default_val;
285 $(let r = $value;)?
286 r
287 };
288
289 c_enum!(@one; $ty_name; $variant + 1; $($tail)*);
292 };
293
294 (@ty $repr:ty) => { $repr };
296 (@ty) => { $crate::prelude::CEnumRepr };
297}
298
299macro_rules! f {
301 ($(
302 $(#[$attr:meta])*
303 pub $(fn $i:ident)? $(const fn $const_i:ident)?
305 ($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
306 $body:block
307 )+) => {$(
308 #[inline]
309 $(#[$attr])*
310 pub $(unsafe extern "C" fn $i)? $(const unsafe extern "C" fn $const_i)?
311 ($($arg: $argty),*) -> $ret
312 $body
313 )+};
314}
315
316macro_rules! safe_f {
318 ($(
319 $(#[$attr:meta])*
320 pub $(fn $i:ident)? $(const fn $const_i:ident)?
322 ($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
323 $body:block
324 )+) => {$(
325 #[inline]
326 $(#[$attr])*
327 pub $(extern "C" fn $i)? $(const extern "C" fn $const_i)?
328 ($($arg: $argty),*) -> $ret
329 $body
330 )+};
331}
332
333macro_rules! __item {
334 ($i:item) => {
335 $i
336 };
337}
338
339macro_rules! deprecated_mach {
341 (pub const $id:ident: $ty:ty = $expr:expr;) => {
342 #[deprecated(
343 since = "0.2.55",
344 note = "Use the `mach2` crate instead",
345 )]
346 #[allow(deprecated)]
347 pub const $id: $ty = $expr;
348 };
349 ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => {
350 $(
351 deprecated_mach!(
352 pub const $id: $ty = $expr;
353 );
354 )*
355 };
356 (pub type $id:ident = $ty:ty;) => {
357 #[deprecated(
358 since = "0.2.55",
359 note = "Use the `mach2` crate instead",
360 )]
361 #[allow(deprecated)]
362 pub type $id = $ty;
363 };
364 ($(pub type $id:ident = $ty:ty;)*) => {
365 $(
366 deprecated_mach!(
367 pub type $id = $ty;
368 );
369 )*
370 }
371}
372
373#[cfg(test)]
374mod tests {
375 use crate::types::CEnumRepr;
376
377 #[test]
378 fn c_enumbasic() {
379 c_enum! {
381 pub enum e {
382 VAR0,
383 VAR1,
384 VAR2,
385 }
386 }
387
388 assert_eq!(VAR0, 0 as CEnumRepr);
389 assert_eq!(VAR1, 1 as CEnumRepr);
390 assert_eq!(VAR2, 2 as CEnumRepr);
391 }
392
393 #[test]
394 fn c_enumrepr() {
395 c_enum! {
397 #[repr(u16)]
398 pub enum e {
399 VAR0,
400 }
401 }
402
403 assert_eq!(VAR0, 0_u16);
404 }
405
406 #[test]
407 fn c_enumset_value() {
408 c_enum! {
410 pub enum e {
411 VAR2 = 2,
412 VAR3,
413 VAR4,
414 }
415 }
416
417 assert_eq!(VAR2, 2 as CEnumRepr);
418 assert_eq!(VAR3, 3 as CEnumRepr);
419 assert_eq!(VAR4, 4 as CEnumRepr);
420 }
421
422 #[test]
423 fn c_enummultiple_set_value() {
424 c_enum! {
427 pub enum e {
428 VAR0,
429 VAR2_0 = 2,
430 VAR3_0,
431 VAR4_0,
432 VAR2_1 = 2,
433 VAR3_1,
434 VAR4_1,
435 }
436 }
437
438 assert_eq!(VAR0, 0 as CEnumRepr);
439 assert_eq!(VAR2_0, 2 as CEnumRepr);
440 assert_eq!(VAR3_0, 3 as CEnumRepr);
441 assert_eq!(VAR4_0, 4 as CEnumRepr);
442 assert_eq!(VAR2_1, 2 as CEnumRepr);
443 assert_eq!(VAR3_1, 3 as CEnumRepr);
444 assert_eq!(VAR4_1, 4 as CEnumRepr);
445 }
446}