1macro_rules! ConstDefault {
10 (
12 $(#[$attr:meta])+
13 $vis:vis enum $enum_name:ident {
14 $($body:tt)*
15 }
16 ) => {
17 $crate::macros::ConstDefault!(enum $enum_name { $($body)* });
18 };
19
20 (
22 $(#[$attr:meta])+
23 $vis:vis struct $struct_name:ident $($rest:tt)*
24 ) => {
25 $crate::macros::ConstDefault!(struct $struct_name $($rest)*);
26 };
27
28 (
30 enum $enum_name:ident {
31 #[custom(default)]
32 $(#[$other_variant_attr:meta])*
33 $variant_name:ident $(= $discriminant:expr)?,
34 $( $rest_of_body:tt )*
35 }
36 ) => {
37 impl $enum_name {
38 pub const fn default() -> Self {
40 Self::$variant_name
41 }
42 }
43
44 impl $crate::macros::ConstDefaultHelper for $enum_name {
45 const DEFAULT: Self = Self::$variant_name;
46 }
47
48 impl ::core::default::Default for $enum_name {
49 fn default() -> Self {
50 Self::$variant_name
51 }
52 }
53 };
54
55 (
57 enum $enum_name:ident {
58 #[$attr_that_is_not_default:meta]
59 $( $rest_of_body:tt )*
60 }
61 ) => {
62 $crate::macros::ConstDefault!(enum $enum_name { $( $rest_of_body )* });
63 };
64
65
66 (
69 enum $enum_name:ident {
70 $variant_name:ident $(= $discriminant:expr)?,
71 $( $rest_of_body:tt )*
72 }
73 ) => {
74 $crate::macros::ConstDefault!(enum $enum_name { $( $rest_of_body )* });
75 };
76 (
77 enum $enum_name:ident {
78 $variant_name:ident ( $( $field_tokens:tt )* ),
79 $( $rest_of_body:tt )*
80 }
81 ) => {
82 $crate::macros::ConstDefault!(enum $enum_name { $( $rest_of_body )* });
83 };
84 (
85 enum $enum_name:ident {
86 $variant_name:ident { $( $field_tokens:tt )* },
87 $( $rest_of_body:tt )*
88 }
89 ) => {
90 $crate::macros::ConstDefault!(enum $enum_name { $( $rest_of_body )* });
91 };
92
93 (
95 $(#[$struct_attr:meta])*
96 $vis:vis struct $struct_name:ident {
97 $(
98 $(#[$field_attr:meta])*
99 $field_vis:vis $field_name:ident : $field_type:ty,
100 )*
101 }
102 ) => {
103 impl $struct_name {
104 pub const fn default() -> Self {
106 <Self as $crate::macros::ConstDefaultHelper>::DEFAULT
107 }
108 }
109
110 impl $crate::macros::ConstDefaultHelper for $struct_name {
111 const DEFAULT: Self = Self {
112 $(
113 $field_name: <$field_type as $crate::macros::ConstDefaultHelper>::DEFAULT,
114 )*
115 };
116 }
117
118 impl ::core::default::Default for $struct_name {
119 fn default() -> Self {
120 <Self as $crate::macros::ConstDefaultHelper>::DEFAULT
121 }
122 }
123 };
124
125
126 (
128 $(#[$struct_attr:meta])*
129 $vis:vis struct $struct_name:ident(
130 $(
131 $(#[$field_attr:meta])*
132 $field_vis:vis $field_type:ty
133 ),* $(,)?
134 );
135 ) => {
136 impl $struct_name {
137 pub const fn default() -> Self {
139 <Self as $crate::macros::ConstDefaultHelper>::DEFAULT
140 }
141 }
142
143 impl $crate::macros::ConstDefaultHelper for $struct_name {
144 const DEFAULT: Self = Self(
145 $(
146 <$field_type as $crate::macros::ConstDefaultHelper>::DEFAULT,
147 )*
148 );
149 }
150
151 impl ::core::default::Default for $struct_name {
152 fn default() -> Self {
153 <Self as $crate::macros::ConstDefaultHelper>::DEFAULT
154 }
155 }
156 };
157}
158pub(crate) use ConstDefault;
159
160pub(crate) trait ConstDefaultHelper {
168 const DEFAULT: Self;
169}
170
171impl ConstDefaultHelper for bool {
172 const DEFAULT: Self = false;
173}
174impl ConstDefaultHelper for f32 {
175 const DEFAULT: Self = 0.;
176}
177impl ConstDefaultHelper for f64 {
178 const DEFAULT: Self = 0.;
179}
180impl ConstDefaultHelper for i32 {
181 const DEFAULT: Self = 0;
182}
183impl ConstDefaultHelper for i64 {
184 const DEFAULT: Self = 0;
185}
186impl ConstDefaultHelper for u32 {
187 const DEFAULT: Self = 0;
188}
189impl ConstDefaultHelper for u64 {
190 const DEFAULT: Self = 0;
191}
192
193impl<T> ConstDefaultHelper for Option<T> {
194 const DEFAULT: Self = None;
195}
196
197impl<T: ConstDefaultHelper, const N: usize> ConstDefaultHelper for [T; N] {
198 const DEFAULT: Self = [<T as ConstDefaultHelper>::DEFAULT; N];
199}