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::{
80 Copy,
81 Send,
82 Sync,
83 };
84 #[allow(unused_imports)]
85 pub(crate) use core::option::Option;
86 #[allow(unused_imports)]
87 pub(crate) use core::prelude::v1::derive;
88 #[allow(unused_imports)]
89 pub(crate) use core::{
90 cfg,
91 fmt,
92 hash,
93 iter,
94 mem,
95 ptr,
96 };
97
98 #[allow(unused_imports)]
99 pub(crate) use fmt::Debug;
100 #[allow(unused_imports)]
101 pub(crate) use mem::{
102 align_of,
103 align_of_val,
104 size_of,
105 size_of_val,
106 };
107
108 #[allow(unused_imports)]
109 pub(crate) use crate::types::{
110 CEnumRepr,
111 Padding,
112 };
113 #[allow(unused_imports)]
115 pub(crate) use crate::{
116 c_char,
117 c_double,
118 c_float,
119 c_int,
120 c_long,
121 c_longlong,
122 c_short,
123 c_uchar,
124 c_uint,
125 c_ulong,
126 c_ulonglong,
127 c_ushort,
128 c_void,
129 intptr_t,
130 size_t,
131 ssize_t,
132 uintptr_t,
133 };
134 }
135 };
136}
137
138macro_rules! s {
144 ($(
145 $(#[$attr:meta])*
146 $pub:vis $t:ident $i:ident { $($field:tt)* }
147 )*) => ($(
148 s!(it: $(#[$attr])* $pub $t $i { $($field)* });
149 )*);
150
151 (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
152 compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
153 );
154
155 (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
156 __item! {
157 #[repr(C)]
158 #[::core::prelude::v1::derive(
159 ::core::clone::Clone,
160 ::core::marker::Copy,
161 ::core::fmt::Debug,
162 )]
163 #[cfg_attr(
164 feature = "extra_traits",
165 ::core::prelude::v1::derive(Eq, Hash, PartialEq)
166 )]
167 #[allow(deprecated)]
168 $(#[$attr])*
169 $pub struct $i { $($field)* }
170 }
171 );
172}
173
174macro_rules! s_paren {
179 ($(
180 $(#[$attr:meta])*
181 pub struct $i:ident ( $($field:tt)* );
182 )*) => ($(
183 __item! {
184 #[cfg_attr(
185 feature = "extra_traits",
186 ::core::prelude::v1::derive(Eq, Hash, PartialEq)
187 )]
188 #[::core::prelude::v1::derive(
189 ::core::clone::Clone,
190 ::core::marker::Copy,
191 ::core::fmt::Debug,
192 )]
193 $(#[$attr])*
194 pub struct $i ( $($field)* );
195 }
196 )*);
197}
198
199macro_rules! s_no_extra_traits {
204 ($(
205 $(#[$attr:meta])*
206 $pub:vis $t:ident $i:ident { $($field:tt)* }
207 )*) => ($(
208 s_no_extra_traits!(it: $(#[$attr])* $pub $t $i { $($field)* });
209 )*);
210
211 (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
212 __item! {
213 #[repr(C)]
214 #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)]
215 $(#[$attr])*
216 $pub union $i { $($field)* }
217 }
218
219 impl ::core::fmt::Debug for $i {
220 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
221 f.debug_struct(::core::stringify!($i)).finish_non_exhaustive()
222 }
223 }
224 );
225
226 (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
227 __item! {
228 #[repr(C)]
229 #[::core::prelude::v1::derive(
230 ::core::clone::Clone,
231 ::core::marker::Copy,
232 ::core::fmt::Debug,
233 )]
234 $(#[$attr])*
235 $pub struct $i { $($field)* }
236 }
237 );
238}
239
240macro_rules! extern_ty {
247 ($(
248 $(#[$attr:meta])*
249 pub enum $i:ident {}
250 )*) => ($(
251 $(#[$attr])*
252 #[::core::prelude::v1::derive(
255 ::core::clone::Clone,
256 ::core::marker::Copy,
257 ::core::fmt::Debug,
258 )]
259 pub enum $i { }
260 )*);
261}
262
263macro_rules! e {
267 ($(
268 $(#[$attr:meta])*
269 pub enum $i:ident { $($field:tt)* }
270 )*) => ($(
271 __item! {
272 #[cfg_attr(
273 feature = "extra_traits",
274 ::core::prelude::v1::derive(Eq, Hash, PartialEq)
275 )]
276 #[::core::prelude::v1::derive(
277 ::core::clone::Clone,
278 ::core::marker::Copy,
279 ::core::fmt::Debug,
280 )]
281 $(#[$attr])*
282 pub enum $i { $($field)* }
283 }
284 )*);
285}
286
287macro_rules! c_enum {
297 ($(
299 $(#[repr($repr:ty)])?
300 pub enum $($ty_name:ident)? $(#$anon:ident)? {
301 $($vis:vis $variant:ident $(= $value:expr)?,)+
302 }
303 )+) => {
304 $(c_enum!(@single;
305 $(#[repr($repr)])?
306 pub enum $($ty_name)? $(#$anon)? {
307 $($vis $variant $(= $value)?,)+
308 }
309 );)+
310 };
311
312 (@single;
314 $(#[repr($repr:ty)])?
315 pub enum $ty_name:ident {
316 $($vis:vis $variant:ident $(= $value:expr)?,)+
317 }
318 ) => {
319 pub type $ty_name = c_enum!(@ty $($repr)?);
320 c_enum! {
321 @variant;
322 ty: $ty_name;
323 default: 0;
324 variants: [$($vis $variant $(= $value)?,)+]
325 }
326 };
327
328 (@single;
330 $(#[repr($repr:ty)])?
331 pub enum #anon {
332 $($vis:vis $variant:ident $(= $value:expr)?,)+
333 }
334 ) => {
335 c_enum! {
336 @variant;
337 ty: c_enum!(@ty $($repr)?);
338 default: 0;
339 variants: [$($vis $variant $(= $value)?,)+]
340 }
341 };
342
343 (@variant; ty: $_ty_name:ty; default: $_idx:expr; variants: []) => { };
345 (
346 @variant;
347 ty: $ty_name:ty;
348 default: $default_val:expr;
349 variants: [
350 $vis:vis $variant:ident $(= $value:expr)?,
351 $($tail:tt)*
352 ]
353 ) => {
354 $vis const $variant: $ty_name = {
355 #[allow(unused_variables)]
356 let r = $default_val;
357 $(let r = $value;)?
358 r
359 };
360
361 c_enum! {
364 @variant;
365 ty: $ty_name;
366 default: $variant + 1;
367 variants: [$($tail)*]
368 }
369 };
370
371 (@ty $repr:ty) => { $repr };
373 (@ty) => { $crate::prelude::CEnumRepr };
374}
375
376macro_rules! f {
378 ($(
379 $(#[$attr:meta])*
380 pub $(fn $i:ident)? $(const fn $const_i:ident)?
382 ($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
383 $body:block
384 )+) => {$(
385 #[inline]
386 $(#[$attr])*
387 pub $(unsafe extern "C" fn $i)? $(const unsafe extern "C" fn $const_i)?
388 ($($arg: $argty),*) -> $ret
389 $body
390 )+};
391}
392
393macro_rules! safe_f {
395 ($(
396 $(#[$attr:meta])*
397 pub $(fn $i:ident)? $(const fn $const_i:ident)?
399 ($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
400 $body:block
401 )+) => {$(
402 #[inline]
403 $(#[$attr])*
404 pub $(extern "C" fn $i)? $(const extern "C" fn $const_i)?
405 ($($arg: $argty),*) -> $ret
406 $body
407 )+};
408}
409
410macro_rules! __item {
411 ($i:item) => {
412 $i
413 };
414}
415
416macro_rules! deprecated_mach {
418 (pub const $id:ident: $ty:ty = $expr:expr;) => {
419 #[deprecated(
420 since = "0.2.55",
421 note = "Use the `mach2` crate instead",
422 )]
423 #[allow(deprecated)]
424 pub const $id: $ty = $expr;
425 };
426 ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => {
427 $(
428 deprecated_mach!(
429 pub const $id: $ty = $expr;
430 );
431 )*
432 };
433 (pub type $id:ident = $ty:ty;) => {
434 #[deprecated(
435 since = "0.2.55",
436 note = "Use the `mach2` crate instead",
437 )]
438 #[allow(deprecated)]
439 pub type $id = $ty;
440 };
441 ($(pub type $id:ident = $ty:ty;)*) => {
442 $(
443 deprecated_mach!(
444 pub type $id = $ty;
445 );
446 )*
447 }
448}
449
450macro_rules! offset_of {
453 ($Ty:path, $field:ident) => {{
454 #[allow(clippy::unneeded_field_pattern)]
456 let $Ty { $field: _, .. };
457 let data = core::mem::MaybeUninit::<$Ty>::uninit();
458 let ptr = data.as_ptr();
459 let fptr = unsafe { core::ptr::addr_of!((*ptr).$field) };
461 let off = (fptr as usize).checked_sub(ptr as usize).unwrap();
462 assert!(off <= core::mem::size_of::<$Ty>());
463 off
464 }};
465}
466
467#[cfg(test)]
468mod tests {
469 use core::any::TypeId;
470
471 use crate::types::CEnumRepr;
472
473 #[test]
474 fn c_enum_basic() {
475 c_enum! {
477 pub enum e {
478 VAR0,
479 VAR1,
480 VAR2,
481 }
482
483 pub enum #anon {
485 ANON0,
486 ANON1,
487 ANON2,
488 }
489 }
490
491 assert_eq!(TypeId::of::<e>(), TypeId::of::<CEnumRepr>());
492 assert_eq!(VAR0, 0 as CEnumRepr);
493 assert_eq!(VAR1, 1 as CEnumRepr);
494 assert_eq!(VAR2, 2 as CEnumRepr);
495
496 assert_eq!(type_id_of_val(&ANON0), TypeId::of::<CEnumRepr>());
497 assert_eq!(ANON0, 0 as CEnumRepr);
498 assert_eq!(ANON1, 1 as CEnumRepr);
499 assert_eq!(ANON2, 2 as CEnumRepr);
500 }
501
502 #[test]
503 fn c_enum_repr() {
504 c_enum! {
506 #[repr(u16)]
507 pub enum e {
508 VAR0,
509 }
510
511 #[repr(u16)]
512 pub enum #anon {
513 ANON0,
514 }
515 }
516
517 assert_eq!(TypeId::of::<e>(), TypeId::of::<u16>());
518 assert_eq!(VAR0, 0_u16);
519
520 assert_eq!(type_id_of_val(&ANON0), TypeId::of::<u16>());
521 assert_eq!(ANON0, 0_u16);
522 }
523
524 #[test]
525 fn c_enum_set_value() {
526 c_enum! {
528 pub enum e {
529 VAR2 = 2,
530 VAR3,
531 VAR4,
532 }
533 }
534
535 assert_eq!(VAR2, 2 as CEnumRepr);
536 assert_eq!(VAR3, 3 as CEnumRepr);
537 assert_eq!(VAR4, 4 as CEnumRepr);
538 }
539
540 #[test]
541 fn c_enum_multiple_set_value() {
542 c_enum! {
545 pub enum e {
546 VAR0,
547 VAR2_0 = 2,
548 VAR3_0,
549 VAR4_0,
550 VAR2_1 = 2,
551 VAR3_1,
552 VAR4_1,
553 }
554 }
555
556 assert_eq!(VAR0, 0 as CEnumRepr);
557 assert_eq!(VAR2_0, 2 as CEnumRepr);
558 assert_eq!(VAR3_0, 3 as CEnumRepr);
559 assert_eq!(VAR4_0, 4 as CEnumRepr);
560 assert_eq!(VAR2_1, 2 as CEnumRepr);
561 assert_eq!(VAR3_1, 3 as CEnumRepr);
562 assert_eq!(VAR4_1, 4 as CEnumRepr);
563 }
564
565 #[test]
566 fn c_enum_vis() {
567 mod priv1 {
568 c_enum! {
569 #[repr(u8)]
570 pub enum e1 {
571 PRIV_ON_1 = 10,
572 pub PUB1 = PRIV_ON_1 * 2,
574 }
575 }
576 }
577 mod priv2 {
578 c_enum! {
579 #[repr(u16)]
580 pub enum e2 {
581 pub PRIV_ON_1 = 42,
582 pub PUB2 = PRIV_ON_1 * 2,
583 }
584 }
585 }
586
587 use priv1::*;
588 use priv2::*;
589
590 assert_eq!(TypeId::of::<e1>(), TypeId::of::<u8>());
591 assert_eq!(TypeId::of::<e2>(), TypeId::of::<u16>());
592 assert_eq!(PUB1, 10u8 * 2);
593 assert_eq!(PUB2, 42u16 * 2);
594 assert_eq!(PRIV_ON_1, 42u16);
597 }
598
599 fn type_id_of_val<T: 'static>(_: &T) -> TypeId {
600 TypeId::of::<T>()
601 }
602
603 #[test]
604 fn test_offset_of() {
605 #[repr(C)]
606 struct Off1 {
607 a: u8,
608 b: u32,
609 c: Off2,
610 d: u64,
611 }
612
613 #[repr(C)]
614 #[repr(align(128))]
615 struct Off2 {}
616
617 assert_eq!(core::mem::offset_of!(Off1, a), offset_of!(Off1, a));
618 assert_eq!(core::mem::offset_of!(Off1, b), offset_of!(Off1, b));
619 assert_eq!(core::mem::offset_of!(Off1, c), offset_of!(Off1, c));
620 assert_eq!(core::mem::offset_of!(Off1, d), offset_of!(Off1, d));
621 }
622}
623
624#[cfg(test)]
625#[allow(unused)]
626mod macro_checks {
627 s! {
628 pub struct S1 {
629 pub a: u32,
630 b: u32,
631 }
632
633 struct S1Priv {
634 pub a: u32,
635 b: u32,
636 }
637 }
638
639 s_no_extra_traits! {
640 pub struct S2 {
641 pub a: u32,
642 b: u32,
643 }
644
645 struct S2Priv {
646 pub a: u32,
647 b: u32,
648 }
649
650 pub union U2 {
651 pub a: u32,
652 b: f32,
653 }
654
655 union U2Priv {
656 pub a: u32,
657 b: f32,
658 }
659 }
660}