@@ -72,10 +72,39 @@ macro_rules! try_or_print {
72
72
// (https://doc.rust-lang.org/nightly/proc_macro/struct.Span.html#method.error),
73
73
// which is currently unstable. Revisit this once it's stable.
74
74
75
- #[ proc_macro_derive( KnownLayout ) ]
76
- pub fn derive_known_layout ( ts : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
77
- let ast = syn:: parse_macro_input!( ts as DeriveInput ) ;
75
+ /// Defines a derive function named `$outer` which parses its input
76
+ /// `TokenStream` as a `DeriveInput` and then invokes the `$inner` function.
77
+ ///
78
+ /// Note that the separate `$outer` parameter is required - proc macro functions
79
+ /// are currently required to live at the crate root, and so the caller must
80
+ /// specify the name in order to avoid name collisions.
81
+ macro_rules! derive {
82
+ ( $trait: ident => $outer: ident => $inner: ident) => {
83
+ #[ proc_macro_derive( $trait) ]
84
+ pub fn $outer( ts: proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
85
+ let ast = syn:: parse_macro_input!( ts as DeriveInput ) ;
86
+ $inner( & ast) . into( )
87
+ }
88
+ } ;
89
+ }
90
+
91
+ derive ! ( KnownLayout => derive_known_layout => derive_known_layout_inner) ;
92
+ derive ! ( NoCell => derive_no_cell => derive_no_cell_inner) ;
93
+ derive ! ( TryFromBytes => derive_try_from_bytes => derive_try_from_bytes_inner) ;
94
+ derive ! ( FromZeros => derive_from_zeros => derive_from_zeros_inner) ;
95
+ derive ! ( FromBytes => derive_from_bytes => derive_from_bytes_inner) ;
96
+ derive ! ( IntoBytes => derive_as_bytes => derive_as_bytes_inner) ;
97
+ derive ! ( Unaligned => derive_unaligned => derive_unaligned_inner) ;
98
+
99
+ /// Deprecated: prefer [`FromZeros`] instead.
100
+ #[ deprecated( since = "0.8.0" , note = "`FromZeroes` was renamed to `FromZeros`" ) ]
101
+ #[ doc( hidden) ]
102
+ #[ proc_macro_derive( FromZeroes ) ]
103
+ pub fn derive_from_zeroes ( ts : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
104
+ derive_from_zeros ( ts)
105
+ }
78
106
107
+ fn derive_known_layout_inner ( ast : & DeriveInput ) -> proc_macro2:: TokenStream {
79
108
let is_repr_c_struct = match & ast. data {
80
109
Data :: Struct ( ..) => {
81
110
let reprs = try_or_print ! ( repr:: reprs:: <Repr >( & ast. attrs) ) ;
@@ -208,7 +237,7 @@ pub fn derive_known_layout(ts: proc_macro::TokenStream) -> proc_macro::TokenStre
208
237
// of an usized trailing field requires that the field is
209
238
// `KnownLayout`.
210
239
impl_block (
211
- & ast,
240
+ ast,
212
241
strct,
213
242
Trait :: KnownLayout ,
214
243
require_trait_bound_on_field_types,
@@ -221,7 +250,7 @@ pub fn derive_known_layout(ts: proc_macro::TokenStream) -> proc_macro::TokenStre
221
250
// A bound on the trailing field is not required, since enums cannot
222
251
// currently be unsized.
223
252
impl_block (
224
- & ast,
253
+ ast,
225
254
enm,
226
255
Trait :: KnownLayout ,
227
256
FieldBounds :: None ,
@@ -234,7 +263,7 @@ pub fn derive_known_layout(ts: proc_macro::TokenStream) -> proc_macro::TokenStre
234
263
// A bound on the trailing field is not required, since unions
235
264
// cannot currently be unsized.
236
265
impl_block (
237
- & ast,
266
+ ast,
238
267
unn,
239
268
Trait :: KnownLayout ,
240
269
FieldBounds :: None ,
@@ -244,112 +273,71 @@ pub fn derive_known_layout(ts: proc_macro::TokenStream) -> proc_macro::TokenStre
244
273
)
245
274
}
246
275
}
247
- . into ( )
248
276
}
249
277
250
- #[ proc_macro_derive( NoCell ) ]
251
- pub fn derive_no_cell ( ts : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
252
- let ast = syn:: parse_macro_input!( ts as DeriveInput ) ;
278
+ fn derive_no_cell_inner ( ast : & DeriveInput ) -> proc_macro2:: TokenStream {
253
279
match & ast. data {
254
280
Data :: Struct ( strct) => impl_block (
255
- & ast,
281
+ ast,
256
282
strct,
257
283
Trait :: NoCell ,
258
284
FieldBounds :: ALL_SELF ,
259
285
SelfBounds :: None ,
260
286
None ,
261
287
None ,
262
288
) ,
263
- Data :: Enum ( enm) => impl_block (
264
- & ast,
265
- enm,
266
- Trait :: NoCell ,
267
- FieldBounds :: ALL_SELF ,
268
- SelfBounds :: None ,
269
- None ,
270
- None ,
271
- ) ,
272
- Data :: Union ( unn) => impl_block (
273
- & ast,
274
- unn,
275
- Trait :: NoCell ,
276
- FieldBounds :: ALL_SELF ,
277
- SelfBounds :: None ,
278
- None ,
279
- None ,
280
- ) ,
289
+ Data :: Enum ( enm) => {
290
+ impl_block ( ast, enm, Trait :: NoCell , FieldBounds :: ALL_SELF , SelfBounds :: None , None , None )
291
+ }
292
+ Data :: Union ( unn) => {
293
+ impl_block ( ast, unn, Trait :: NoCell , FieldBounds :: ALL_SELF , SelfBounds :: None , None , None )
294
+ }
281
295
}
282
- . into ( )
283
296
}
284
297
285
- #[ proc_macro_derive( TryFromBytes ) ]
286
- pub fn derive_try_from_bytes ( ts : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
287
- let ast = syn:: parse_macro_input!( ts as DeriveInput ) ;
298
+ fn derive_try_from_bytes_inner ( ast : & DeriveInput ) -> proc_macro2:: TokenStream {
288
299
match & ast. data {
289
- Data :: Struct ( strct) => derive_try_from_bytes_struct ( & ast, strct) ,
290
- Data :: Enum ( enm) => derive_try_from_bytes_enum ( & ast, enm) ,
291
- Data :: Union ( unn) => derive_try_from_bytes_union ( & ast, unn) ,
300
+ Data :: Struct ( strct) => derive_try_from_bytes_struct ( ast, strct) ,
301
+ Data :: Enum ( enm) => derive_try_from_bytes_enum ( ast, enm) ,
302
+ Data :: Union ( unn) => derive_try_from_bytes_union ( ast, unn) ,
292
303
}
293
- . into ( )
294
304
}
295
305
296
- #[ proc_macro_derive( FromZeros ) ]
297
- pub fn derive_from_zeros ( ts : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
298
- let try_from_bytes = derive_try_from_bytes ( ts. clone ( ) ) ;
299
-
300
- let ast = syn:: parse_macro_input!( ts as DeriveInput ) ;
306
+ fn derive_from_zeros_inner ( ast : & DeriveInput ) -> proc_macro2:: TokenStream {
307
+ let try_from_bytes = derive_try_from_bytes_inner ( ast) ;
301
308
let from_zeros = match & ast. data {
302
- Data :: Struct ( strct) => derive_from_zeros_struct ( & ast, strct) ,
303
- Data :: Enum ( enm) => derive_from_zeros_enum ( & ast, enm) ,
304
- Data :: Union ( unn) => derive_from_zeros_union ( & ast, unn) ,
305
- }
306
- . into ( ) ;
309
+ Data :: Struct ( strct) => derive_from_zeros_struct ( ast, strct) ,
310
+ Data :: Enum ( enm) => derive_from_zeros_enum ( ast, enm) ,
311
+ Data :: Union ( unn) => derive_from_zeros_union ( ast, unn) ,
312
+ } ;
307
313
IntoIterator :: into_iter ( [ try_from_bytes, from_zeros] ) . collect ( )
308
314
}
309
315
310
- /// Deprecated: prefer [`FromZeros`] instead.
311
- #[ deprecated( since = "0.8.0" , note = "`FromZeroes` was renamed to `FromZeros`" ) ]
312
- #[ doc( hidden) ]
313
- #[ proc_macro_derive( FromZeroes ) ]
314
- pub fn derive_from_zeroes ( ts : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
315
- derive_from_zeros ( ts)
316
- }
317
-
318
- #[ proc_macro_derive( FromBytes ) ]
319
- pub fn derive_from_bytes ( ts : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
320
- let from_zeros = derive_from_zeros ( ts. clone ( ) ) ;
321
-
322
- let ast = syn:: parse_macro_input!( ts as DeriveInput ) ;
316
+ fn derive_from_bytes_inner ( ast : & DeriveInput ) -> proc_macro2:: TokenStream {
317
+ let from_zeros = derive_from_zeros_inner ( ast) ;
323
318
let from_bytes = match & ast. data {
324
- Data :: Struct ( strct) => derive_from_bytes_struct ( & ast, strct) ,
325
- Data :: Enum ( enm) => derive_from_bytes_enum ( & ast, enm) ,
326
- Data :: Union ( unn) => derive_from_bytes_union ( & ast, unn) ,
327
- }
328
- . into ( ) ;
319
+ Data :: Struct ( strct) => derive_from_bytes_struct ( ast, strct) ,
320
+ Data :: Enum ( enm) => derive_from_bytes_enum ( ast, enm) ,
321
+ Data :: Union ( unn) => derive_from_bytes_union ( ast, unn) ,
322
+ } ;
329
323
330
324
IntoIterator :: into_iter ( [ from_zeros, from_bytes] ) . collect ( )
331
325
}
332
326
333
- #[ proc_macro_derive( IntoBytes ) ]
334
- pub fn derive_as_bytes ( ts : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
335
- let ast = syn:: parse_macro_input!( ts as DeriveInput ) ;
327
+ fn derive_as_bytes_inner ( ast : & DeriveInput ) -> proc_macro2:: TokenStream {
336
328
match & ast. data {
337
- Data :: Struct ( strct) => derive_as_bytes_struct ( & ast, strct) ,
338
- Data :: Enum ( enm) => derive_as_bytes_enum ( & ast, enm) ,
339
- Data :: Union ( unn) => derive_as_bytes_union ( & ast, unn) ,
329
+ Data :: Struct ( strct) => derive_as_bytes_struct ( ast, strct) ,
330
+ Data :: Enum ( enm) => derive_as_bytes_enum ( ast, enm) ,
331
+ Data :: Union ( unn) => derive_as_bytes_union ( ast, unn) ,
340
332
}
341
- . into ( )
342
333
}
343
334
344
- #[ proc_macro_derive( Unaligned ) ]
345
- pub fn derive_unaligned ( ts : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
346
- let ast = syn:: parse_macro_input!( ts as DeriveInput ) ;
335
+ fn derive_unaligned_inner ( ast : & DeriveInput ) -> proc_macro2:: TokenStream {
347
336
match & ast. data {
348
- Data :: Struct ( strct) => derive_unaligned_struct ( & ast, strct) ,
349
- Data :: Enum ( enm) => derive_unaligned_enum ( & ast, enm) ,
350
- Data :: Union ( unn) => derive_unaligned_union ( & ast, unn) ,
337
+ Data :: Struct ( strct) => derive_unaligned_struct ( ast, strct) ,
338
+ Data :: Enum ( enm) => derive_unaligned_enum ( ast, enm) ,
339
+ Data :: Union ( unn) => derive_unaligned_union ( ast, unn) ,
351
340
}
352
- . into ( )
353
341
}
354
342
355
343
// A struct is `TryFromBytes` if:
0 commit comments