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 | |