@@ -43,7 +43,7 @@ impl Parse for MhAttr {
43
43
/// Attributes of the top-level derive.
44
44
#[ derive( Debug ) ]
45
45
enum DeriveAttr {
46
- AllocSize ( utils:: Attr < kw:: alloc_size , syn:: Type > ) ,
46
+ AllocSize ( utils:: Attr < kw:: alloc_size , syn:: LitInt > ) ,
47
47
NoAllocSizeErrors ( kw:: no_alloc_size_errors ) ,
48
48
}
49
49
@@ -161,7 +161,7 @@ impl<'a> From<&'a VariantInfo<'a>> for Hash {
161
161
/// Parse top-level enum [#mh()] attributes.
162
162
///
163
163
/// Returns the `alloc_size` and whether errors regarding to `alloc_size` should be reported or not.
164
- fn parse_code_enum_attrs ( ast : & syn:: DeriveInput ) -> ( syn:: Type , bool ) {
164
+ fn parse_code_enum_attrs ( ast : & syn:: DeriveInput ) -> ( syn:: LitInt , bool ) {
165
165
let mut alloc_size = None ;
166
166
let mut no_alloc_size_errors = false ;
167
167
@@ -226,33 +226,12 @@ fn error_code_duplicates(hashes: &[Hash]) {
226
226
#[ derive( Debug ) ]
227
227
struct ParseError ( proc_macro2:: Span ) ;
228
228
229
- /// Parse a path containing a `typenum` unsigned integer (e.g. `U64`) into a u64
230
- fn parse_unsigned_typenum ( typenum_path : & syn:: Type ) -> Result < u64 , ParseError > {
231
- match typenum_path {
232
- syn:: Type :: Path ( type_path) => match type_path. path . segments . last ( ) {
233
- Some ( path_segment) => {
234
- let typenum_ident = & path_segment. ident ;
235
- let typenum = typenum_ident. to_string ( ) ;
236
- match typenum. as_str ( ) . split_at ( 1 ) {
237
- ( "U" , byte_size) => byte_size
238
- . parse :: < u64 > ( )
239
- . map_err ( |_| ParseError ( typenum_ident. span ( ) ) ) ,
240
- _ => Err ( ParseError ( typenum_ident. span ( ) ) ) ,
241
- }
242
- }
243
- None => Err ( ParseError ( type_path. path . span ( ) ) ) ,
244
- } ,
245
- _ => Err ( ParseError ( typenum_path. span ( ) ) ) ,
246
- }
247
- }
248
-
249
229
/// Returns the max size as u64.
250
230
///
251
- /// Emits an error if the `#mh(alloc_size)` attribute doesn't contain a valid unsigned integer
252
- /// `typenum`.
253
- fn parse_alloc_size_attribute ( alloc_size : & syn:: Type ) -> u64 {
254
- parse_unsigned_typenum ( & alloc_size) . unwrap_or_else ( |_| {
255
- let msg = "`alloc_size` attribute must be a `typenum`, e.g. #[mh(alloc_size = U64)]" ;
231
+ /// Emits an error if the `#mh(alloc_size)` attribute doesn't contain a valid unsigned integer.
232
+ fn parse_alloc_size_attribute ( alloc_size : & syn:: LitInt ) -> u64 {
233
+ alloc_size. base10_parse ( ) . unwrap_or_else ( |_| {
234
+ let msg = "`alloc_size` attribute must be an integer, e.g. #[mh(alloc_size = 64)]" ;
256
235
#[ cfg( test) ]
257
236
panic ! ( msg) ;
258
237
#[ cfg( not( test) ) ]
@@ -261,38 +240,39 @@ fn parse_alloc_size_attribute(alloc_size: &syn::Type) -> u64 {
261
240
}
262
241
263
242
/// Return a warning/error if the specified alloc_size is smaller than the biggest digest
264
- fn error_alloc_size ( hashes : & [ Hash ] , expected_alloc_size_type : & syn:: Type ) {
243
+ fn error_alloc_size ( hashes : & [ Hash ] , expected_alloc_size_type : & syn:: LitInt ) {
265
244
let expected_alloc_size = parse_alloc_size_attribute ( expected_alloc_size_type) ;
266
245
267
246
let maybe_error: Result < ( ) , ParseError > = hashes
268
247
. iter ( )
269
248
. try_for_each ( |hash| {
270
- // The digest type must have a size parameter of the shape `U<number>` , else we error.
249
+ // The digest type must have an integer as size parameter , else we error.
271
250
match hash. digest . segments . last ( ) {
272
251
Some ( path_segment) => match & path_segment. arguments {
273
252
syn:: PathArguments :: AngleBracketed ( arguments) => match arguments. args . last ( ) {
274
- Some ( syn:: GenericArgument :: Type ( path) ) => {
275
- match parse_unsigned_typenum ( & path) {
276
- Ok ( max_digest_size) => {
277
- if max_digest_size > expected_alloc_size {
278
- let msg = format ! ( "The `#mh(alloc_size) attribute must be bigger than the maximum defined digest size (U{})" ,
279
- max_digest_size) ;
280
- #[ cfg( test) ]
281
- panic ! ( msg) ;
282
- #[ cfg( not( test) ) ]
283
- {
284
- let digest = & hash. digest . to_token_stream ( ) . to_string ( ) . replace ( " " , "" ) ;
285
- let line = & hash. digest . span ( ) . start ( ) . line ;
286
- proc_macro_error:: emit_error!(
287
- & expected_alloc_size_type, msg;
288
- note = "the bigger digest is `{}` at line {}" , digest, line;
289
- ) ;
290
- }
291
- }
292
- Ok ( ( ) )
293
- } ,
294
- Err ( err) => Err ( err) ,
295
- }
253
+ Some ( syn:: GenericArgument :: Const ( syn:: Expr :: Lit ( expr_lit) ) ) => match & expr_lit. lit {
254
+ syn:: Lit :: Int ( lit_int) => match lit_int. base10_parse :: < u64 > ( ) {
255
+ Ok ( max_digest_size) => {
256
+ if max_digest_size > expected_alloc_size {
257
+ let msg = format ! ( "The `#mh(alloc_size) attribute must be bigger than the maximum defined digest size ({})" ,
258
+ max_digest_size) ;
259
+ #[ cfg( test) ]
260
+ panic ! ( msg) ;
261
+ #[ cfg( not( test) ) ]
262
+ {
263
+ let digest = & hash. digest . to_token_stream ( ) . to_string ( ) . replace ( " " , "" ) ;
264
+ let line = & hash. digest . span ( ) . start ( ) . line ;
265
+ proc_macro_error:: emit_error!(
266
+ & expected_alloc_size_type, msg;
267
+ note = "the bigger digest is `{}` at line {}" , digest, line;
268
+ ) ;
269
+ }
270
+ }
271
+ Ok ( ( ) )
272
+ } ,
273
+ _ => Err ( ParseError ( lit_int. span ( ) ) ) ,
274
+ } ,
275
+ _ => Err ( ParseError ( expr_lit. span ( ) ) ) ,
296
276
} ,
297
277
_ => Err ( ParseError ( arguments. args . span ( ) ) ) ,
298
278
} ,
@@ -338,9 +318,7 @@ pub fn multihash(s: Structure) -> TokenStream {
338
318
/// A Multihash with the same allocated size as the Multihashes produces by this derive.
339
319
pub type Multihash = #mh_crate:: MultihashGeneric :: <#alloc_size>;
340
320
341
- impl #mh_crate:: MultihashDigest for #code_enum {
342
- type AllocSize = #alloc_size;
343
-
321
+ impl #mh_crate:: MultihashDigest <#alloc_size> for #code_enum {
344
322
fn digest( & self , input: & [ u8 ] ) -> Multihash {
345
323
use #mh_crate:: Hasher ;
346
324
match self {
@@ -349,10 +327,9 @@ pub fn multihash(s: Structure) -> TokenStream {
349
327
}
350
328
}
351
329
352
- fn multihash_from_digest<' a, S , D >( digest: & ' a D ) -> Multihash
330
+ fn multihash_from_digest<' a, D >( digest: & ' a D ) -> Multihash
353
331
where
354
- S : #mh_crate:: Size ,
355
- D : #mh_crate:: Digest <S >,
332
+ D : #mh_crate:: Digest <#alloc_size>,
356
333
Self : From <& ' a D >,
357
334
{
358
335
let code = Self :: from( & digest) ;
0 commit comments