1#![no_std]
2#![warn(clippy::pedantic, missing_docs, clippy::cargo)]
3#![allow(clippy::wildcard_imports)]
4#![cfg_attr(docsrs, feature(doc_auto_cfg))]
5#![doc = include_str!("doc.md")]
6
7#[macro_export]
8#[doc = include_str!("doc.md")]
9macro_rules! non_exhaustive {
10 {$type:ty {$($field:ident: $value:expr,)* ..$default:expr}} => {{
11 #[allow(unused)]
12 let mut value: $type = $default;
13 $(value.$field = $value;)*
14 value
15 }};
16 {$type:ty {$($field:ident: $value:expr),* $(,)?}} => {
17 $crate::non_exhaustive!($type {$($field: $value,)* ..::core::default::Default::default()})
18 };
19}
20
21#[cfg(test)]
22#[allow(clippy::all, unused, clippy::pedantic)]
23mod test {
24 use crate::non_exhaustive;
25
26 #[non_exhaustive]
27 #[derive(Default)]
28 struct Test {
29 a: usize,
30 b: usize,
31 c: usize,
32 }
33
34 #[test]
35 #[rustfmt::skip]
36 fn test() {
37 non_exhaustive!(Test {});
38 non_exhaustive!(Test { a: 1 });
39 non_exhaustive!(Test { a: 1, a: 2 });
40 non_exhaustive!(Test { a: 1, a: 2, a: 3 });
41 non_exhaustive!(Test { a: 1, });
42 non_exhaustive!(Test { a: 1, a: 2, });
43 non_exhaustive!(Test { a: 1, a: 2, a: 3, });
44 non_exhaustive!(Test { ..Default::default() });
45 non_exhaustive!(Test { a: 1, ..Default::default() });
46 non_exhaustive!(Test { a: 1, a: 2, ..Default::default() });
47 non_exhaustive!(Test { a: 1, a: 2, a: 3, ..Default::default() });
48 }
49}