1 /// Asserts that the type has the given fields.
2 ///
3 /// # Examples
4 ///
5 /// One common use case is when types have fields defined multiple times as a
6 /// result of `#[cfg]`. This can be an issue when exposing a public API.
7 ///
8 /// ```
9 /// # #[macro_use] extern crate static_assertions;
10 /// pub struct Ty {
11 ///     #[cfg(windows)]
12 ///     pub val1: u8,
13 ///     #[cfg(not(windows))]
14 ///     pub val1: usize,
15 ///
16 ///     #[cfg(unix)]
17 ///     pub val2: u32,
18 ///     #[cfg(not(unix))]
19 ///     pub val2: usize,
20 /// }
21 ///
22 /// // Always have `val2` regardless of OS
23 /// assert_fields!(Ty: val2);
24 /// ```
25 ///
26 /// This macro even works with `enum` variants:
27 ///
28 /// ```
29 /// # #[macro_use] extern crate static_assertions; fn main() {}
30 /// enum Data {
31 ///     Val {
32 ///         id: i32,
33 ///         name: String,
34 ///         bytes: [u8; 128],
35 ///     },
36 ///     Ptr(*const u8),
37 /// }
38 ///
39 /// assert_fields!(Data::Val: id, bytes);
40 /// ```
41 ///
42 /// The following example fails to compile because [`Range`] does not have a field named `middle`:
43 ///
44 /// ```compile_fail
45 /// # #[macro_use] extern crate static_assertions; fn main() {}
46 /// use std::ops::Range;
47 ///
48 /// assert_fields!(Range<u32>: middle);
49 /// ```
50 ///
51 /// [`Range`]: https://doc.rust-lang.org/std/ops/struct.Range.html
52 #[macro_export]
53 macro_rules! assert_fields {
54     ($t:ident::$v:ident: $($f:ident),+) => {
55         #[allow(unknown_lints, unneeded_field_pattern)]
56         const _: fn() = || {
57             #[allow(dead_code, unreachable_patterns)]
58             fn assert(value: $t) {
59                 match value {
60                     $($t::$v { $f: _, .. } => {},)+
61                     _ => {}
62                 }
63             }
64         };
65     };
66     ($t:path: $($f:ident),+) => {
67         #[allow(unknown_lints, unneeded_field_pattern)]
68         const _: fn() = || {
69             $(let $t { $f: _, .. };)+
70         };
71     };
72 }
73