| 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 |
Definitions
Learn Rust with the experts
Find out more
