1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#![no_std]
#![warn(clippy::pedantic, missing_docs, clippy::cargo)]
#![allow(clippy::wildcard_imports)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("doc.md")]

#[macro_export]
#[doc = include_str!("doc.md")]
macro_rules! non_exhaustive {
    {$type:ty {$($field:ident: $value:expr,)* ..$default:expr}} => {{
        #[allow(unused)]
        let mut value: $type = $default;
        $(value.$field = $value;)*
        value
    }};
    {$type:ty {$($field:ident: $value:expr),* $(,)?}} => {
        $crate::non_exhaustive!($type {$($field: $value,)* ..::core::default::Default::default()})
    };
}

#[cfg(test)]
#[allow(clippy::all, unused, clippy::pedantic)]
mod test {
    use crate::non_exhaustive;

    #[non_exhaustive]
    #[derive(Default)]
    struct Test {
        a: usize,
        b: usize,
        c: usize,
    }

    #[test]
    #[rustfmt::skip]
    fn test() {
        non_exhaustive!(Test {});
        non_exhaustive!(Test { a: 1 });
        non_exhaustive!(Test { a: 1, a: 2 });
        non_exhaustive!(Test { a: 1, a: 2, a: 3 });
        non_exhaustive!(Test { a: 1, });
        non_exhaustive!(Test { a: 1, a: 2, });
        non_exhaustive!(Test { a: 1, a: 2, a: 3, });
        non_exhaustive!(Test { ..Default::default() });
        non_exhaustive!(Test { a: 1, ..Default::default() });
        non_exhaustive!(Test { a: 1, a: 2, ..Default::default() });
        non_exhaustive!(Test { a: 1, a: 2, a: 3, ..Default::default() });
    }
}