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 {
146 ($(
147 $(#[$attr:meta])*
148 $pub:vis $t:ident $i:ident { $($field:tt)* }
149 )*) => ($(
150 s!(it: $(#[$attr])* $pub $t $i { $($field)* });
151 )*);
152
153 (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
154 compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
155 );
156
157 (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
158 #[repr(C)]
159 #[::core::prelude::v1::derive(
160 ::core::clone::Clone,
161 ::core::marker::Copy,
162 ::core::fmt::Debug,
163 )]
164 #[cfg_attr(
165 feature = "extra_traits",
166 ::core::prelude::v1::derive(PartialEq, Eq, Hash)
167 )]
168 #[allow(deprecated)]
169 $(#[$attr])*
170 $pub struct $i { $($field)* }
171 );
172}
173
174macro_rules! s_paren {
180 ($(
181 $(#[$attr:meta])*
182 $pub:vis struct $i:ident ( $($field:tt)* );
183 )*) => ($(
184 #[::core::prelude::v1::derive(
185 ::core::clone::Clone,
186 ::core::marker::Copy,
187 ::core::fmt::Debug,
188 )]
189 #[cfg_attr(
190 feature = "extra_traits",
191 ::core::prelude::v1::derive(PartialEq, Eq, Hash)
192 )]
193 $(#[$attr])*
194 $pub struct $i ( $($field)* );
195 )*);
196}
197
198macro_rules! s_no_extra_traits {
205 ($(
206 $(#[$attr:meta])*
207 $pub:vis $t:ident $i:ident { $($field:tt)* }
208 )*) => ($(
209 s_no_extra_traits!(it: $(#[$attr])* $pub $t $i { $($field)* });
210 )*);
211
212 (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
213 #[repr(C)]
214 #[::core::prelude::v1::derive(
215 ::core::clone::Clone,
216 ::core::marker::Copy,
217 )]
218 $(#[$attr])*
219 $pub union $i { $($field)* }
220
221 impl ::core::fmt::Debug for $i {
222 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
223 f.debug_struct(::core::stringify!($i)).finish_non_exhaustive()
224 }
225 }
226 );
227
228 (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
229 #[repr(C)]
230 #[::core::prelude::v1::derive(
231 ::core::clone::Clone,
232 ::core::marker::Copy,
233 ::core::fmt::Debug,
234 )]
235 $(#[$attr])*
236 $pub struct $i { $($field)* }
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 #[cfg_attr(
272 feature = "extra_traits",
273 ::core::prelude::v1::derive(Eq, Hash, PartialEq)
274 )]
275 #[::core::prelude::v1::derive(
276 ::core::clone::Clone,
277 ::core::marker::Copy,
278 ::core::fmt::Debug,
279 )]
280 $(#[$attr])*
281 pub enum $i { $($field)* }
282 )*);
283}
284
285macro_rules! c_enum {
295 ($(
297 $(#[repr($repr:ty)])?
298 pub enum $($ty_name:ident)? $(#$anon:ident)? {
299 $($vis:vis $variant:ident $(= $value:expr)?,)+
300 }
301 )+) => {
302 $(c_enum!(@single;
303 $(#[repr($repr)])?
304 pub enum $($ty_name)? $(#$anon)? {
305 $($vis $variant $(= $value)?,)+
306 }
307 );)+
308 };
309
310 (@single;
312 $(#[repr($repr:ty)])?
313 pub enum $ty_name:ident {
314 $($vis:vis $variant:ident $(= $value:expr)?,)+
315 }
316 ) => {
317 pub type $ty_name = c_enum!(@ty $($repr)?);
318 c_enum! {
319 @variant;
320 ty: $ty_name;
321 default: 0;
322 variants: [$($vis $variant $(= $value)?,)+]
323 }
324 };
325
326 (@single;
328 $(#[repr($repr:ty)])?
329 pub enum #anon {
330 $($vis:vis $variant:ident $(= $value:expr)?,)+
331 }
332 ) => {
333 c_enum! {
334 @variant;
335 ty: c_enum!(@ty $($repr)?);
336 default: 0;
337 variants: [$($vis $variant $(= $value)?,)+]
338 }
339 };
340
341 (@variant; ty: $_ty_name:ty; default: $_idx:expr; variants: []) => { };
343 (
344 @variant;
345 ty: $ty_name:ty;
346 default: $default_val:expr;
347 variants: [
348 $vis:vis $variant:ident $(= $value:expr)?,
349 $($tail:tt)*
350 ]
351 ) => {
352 $vis const $variant: $ty_name = {
353 #[allow(unused_variables)]
354 let r = $default_val;
355 $(let r = $value;)?
356 r
357 };
358
359 c_enum! {
362 @variant;
363 ty: $ty_name;
364 default: $variant + 1;
365 variants: [$($tail)*]
366 }
367 };
368
369 (@ty $repr:ty) => { $repr };
371 (@ty) => { $crate::prelude::CEnumRepr };
372}
373
374macro_rules! f {
376 ($(
377 $(#[$attr:meta])*
378 pub $(fn $i:ident)? $(const fn $const_i:ident)?
380 ($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
381 $body:block
382 )+) => {$(
383 #[inline]
384 $(#[$attr])*
385 pub $(unsafe extern "C" fn $i)? $(const unsafe extern "C" fn $const_i)?
386 ($($arg: $argty),*) -> $ret
387 $body
388 )+};
389}
390
391macro_rules! safe_f {
393 ($(
394 $(#[$attr:meta])*
395 pub $(fn $i:ident)? $(const fn $const_i:ident)?
397 ($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
398 $body:block
399 )+) => {$(
400 #[inline]
401 $(#[$attr])*
402 pub $(extern "C" fn $i)? $(const extern "C" fn $const_i)?
403 ($($arg: $argty),*) -> $ret
404 $body
405 )+};
406}
407
408macro_rules! deprecated_mach {
410 (pub const $id:ident: $ty:ty = $expr:expr;) => {
411 #[deprecated(
412 since = "0.2.55",
413 note = "Use the `mach2` crate instead",
414 )]
415 #[allow(deprecated)]
416 pub const $id: $ty = $expr;
417 };
418 ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => {
419 $(
420 deprecated_mach!(
421 pub const $id: $ty = $expr;
422 );
423 )*
424 };
425 (pub type $id:ident = $ty:ty;) => {
426 #[deprecated(
427 since = "0.2.55",
428 note = "Use the `mach2` crate instead",
429 )]
430 #[allow(deprecated)]
431 pub type $id = $ty;
432 };
433 ($(pub type $id:ident = $ty:ty;)*) => {
434 $(
435 deprecated_mach!(
436 pub type $id = $ty;
437 );
438 )*
439 }
440}
441
442macro_rules! offset_of {
445 ($Ty:path, $field:ident) => {{
446 #[allow(clippy::unneeded_field_pattern)]
448 let $Ty { $field: _, .. };
449 let data = core::mem::MaybeUninit::<$Ty>::uninit();
450 let ptr = data.as_ptr();
451 #[allow(unused_unsafe)]
453 let fptr = unsafe { core::ptr::addr_of!((*ptr).$field) };
455 let off = (fptr as usize).checked_sub(ptr as usize).unwrap();
456 core::assert!(off <= core::mem::size_of::<$Ty>());
457 off
458 }};
459}
460
461#[cfg(test)]
462mod tests {
463 use core::any::TypeId;
464
465 use crate::types::CEnumRepr;
466
467 #[test]
468 fn c_enum_basic() {
469 c_enum! {
471 pub enum e {
472 VAR0,
473 VAR1,
474 VAR2,
475 }
476
477 pub enum #anon {
479 ANON0,
480 ANON1,
481 ANON2,
482 }
483 }
484
485 assert_eq!(TypeId::of::<e>(), TypeId::of::<CEnumRepr>());
486 assert_eq!(VAR0, 0 as CEnumRepr);
487 assert_eq!(VAR1, 1 as CEnumRepr);
488 assert_eq!(VAR2, 2 as CEnumRepr);
489
490 assert_eq!(type_id_of_val(&ANON0), TypeId::of::<CEnumRepr>());
491 assert_eq!(ANON0, 0 as CEnumRepr);
492 assert_eq!(ANON1, 1 as CEnumRepr);
493 assert_eq!(ANON2, 2 as CEnumRepr);
494 }
495
496 #[test]
497 fn c_enum_repr() {
498 c_enum! {
500 #[repr(u16)]
501 pub enum e {
502 VAR0,
503 }
504
505 #[repr(u16)]
506 pub enum #anon {
507 ANON0,
508 }
509 }
510
511 assert_eq!(TypeId::of::<e>(), TypeId::of::<u16>());
512 assert_eq!(VAR0, 0_u16);
513
514 assert_eq!(type_id_of_val(&ANON0), TypeId::of::<u16>());
515 assert_eq!(ANON0, 0_u16);
516 }
517
518 #[test]
519 fn c_enum_set_value() {
520 c_enum! {
522 pub enum e {
523 VAR2 = 2,
524 VAR3,
525 VAR4,
526 }
527 }
528
529 assert_eq!(VAR2, 2 as CEnumRepr);
530 assert_eq!(VAR3, 3 as CEnumRepr);
531 assert_eq!(VAR4, 4 as CEnumRepr);
532 }
533
534 #[test]
535 fn c_enum_multiple_set_value() {
536 c_enum! {
539 pub enum e {
540 VAR0,
541 VAR2_0 = 2,
542 VAR3_0,
543 VAR4_0,
544 VAR2_1 = 2,
545 VAR3_1,
546 VAR4_1,
547 }
548 }
549
550 assert_eq!(VAR0, 0 as CEnumRepr);
551 assert_eq!(VAR2_0, 2 as CEnumRepr);
552 assert_eq!(VAR3_0, 3 as CEnumRepr);
553 assert_eq!(VAR4_0, 4 as CEnumRepr);
554 assert_eq!(VAR2_1, 2 as CEnumRepr);
555 assert_eq!(VAR3_1, 3 as CEnumRepr);
556 assert_eq!(VAR4_1, 4 as CEnumRepr);
557 }
558
559 #[test]
560 fn c_enum_vis() {
561 mod priv1 {
562 c_enum! {
563 #[repr(u8)]
564 pub enum e1 {
565 PRIV_ON_1 = 10,
566 pub PUB1 = PRIV_ON_1 * 2,
568 }
569 }
570 }
571 mod priv2 {
572 c_enum! {
573 #[repr(u16)]
574 pub enum e2 {
575 pub PRIV_ON_1 = 42,
576 pub PUB2 = PRIV_ON_1 * 2,
577 }
578 }
579 }
580
581 use priv1::*;
582 use priv2::*;
583
584 assert_eq!(TypeId::of::<e1>(), TypeId::of::<u8>());
585 assert_eq!(TypeId::of::<e2>(), TypeId::of::<u16>());
586 assert_eq!(PUB1, 10u8 * 2);
587 assert_eq!(PUB2, 42u16 * 2);
588 assert_eq!(PRIV_ON_1, 42u16);
591 }
592
593 fn type_id_of_val<T: 'static>(_: &T) -> TypeId {
594 TypeId::of::<T>()
595 }
596
597 #[test]
598 fn test_offset_of() {
599 #[repr(C)]
600 struct Off1 {
601 a: u8,
602 b: u32,
603 c: Off2,
604 d: u64,
605 }
606
607 #[repr(C)]
608 #[repr(align(128))]
609 struct Off2 {}
610
611 assert_eq!(core::mem::offset_of!(Off1, a), offset_of!(Off1, a));
612 assert_eq!(core::mem::offset_of!(Off1, b), offset_of!(Off1, b));
613 assert_eq!(core::mem::offset_of!(Off1, c), offset_of!(Off1, c));
614 assert_eq!(core::mem::offset_of!(Off1, d), offset_of!(Off1, d));
615 }
616}
617
618#[cfg(test)]
619#[allow(unused)]
620mod macro_checks {
621 s! {
622 pub struct S1 {
623 pub a: u32,
624 b: u32,
625 }
626
627 struct S1Priv {
628 pub a: u32,
629 b: u32,
630 }
631 }
632
633 s_no_extra_traits! {
634 pub struct S2 {
635 pub a: u32,
636 b: u32,
637 }
638
639 struct S2Priv {
640 pub a: u32,
641 b: u32,
642 }
643
644 pub union U2 {
645 pub a: u32,
646 b: f32,
647 }
648
649 union U2Priv {
650 pub a: u32,
651 b: f32,
652 }
653 }
654}