1-  use  anyhow:: { bail,  Error } ; 
1+ use  anyhow:: { bail,  Error } ; 
22use  proc_macro2:: TokenStream ; 
33use  quote:: quote; 
4- use  syn:: { Meta ,   Lit ,   MetaNameValue ,   Path ,   Expr ,   ExprLit } ; 
4+ use  syn:: { Expr ,   ExprLit ,   Lit ,   Meta ,   MetaNameValue ,   Path } ; 
55
6- use  crate :: field:: { set_bool,  word_attr} ; 
6+ use  crate :: field:: { set_bool,  set_option ,   word_attr} ; 
77
88#[ derive( Clone ) ]  
99pub  struct  Field  { 
@@ -14,28 +14,21 @@ impl Field {
1414    pub  fn  new ( attrs :  & [ Meta ] )  -> Result < Option < Field > ,  Error >  { 
1515        let  mut  skip = false ; 
1616        let  mut  default_fn = None ; 
17+         let  mut  default_lit = None ; 
1718        let  mut  unknown_attrs = Vec :: new ( ) ; 
1819
1920        for  attr in  attrs { 
2021            if  word_attr ( "skip" ,  attr)  { 
2122                set_bool ( & mut  skip,  "duplicate skip attribute" ) ?; 
2223            }  else  if  let  Meta :: NameValue ( MetaNameValue  {  path,  value,  .. } )  = attr { 
2324                if  path. is_ident ( "default" )  { 
24-                     let  lit_str =  match  value { 
25+                     match  value { 
2526                        // There has to be a better way... 
26-                         Expr :: Lit ( ExprLit  {  lit :  Lit :: Str ( lit) ,  .. } )  => Some ( lit) , 
27-                         _ => None , 
27+                         Expr :: Lit ( ExprLit  { 
28+                             lit :  Lit :: Str ( lit) ,  ..
29+                         } )  => set_option ( & mut  default_lit,  lit,  "duplicate default attributes" ) ?, 
30+                         _ => bail ! ( "default attribute value must be a string literal" ) , 
2831                    } ; 
29-                     if  let  Some ( lit)  = lit_str { 
30-                         let  fn_path:  Path  = syn:: parse_str ( & lit. value ( ) ) 
31-                             . map_err ( |_| anyhow:: anyhow!( "invalid path for default function" ) ) ?; 
32-                         if  default_fn. is_some ( )  { 
33-                             bail ! ( "duplicate default attribute for skipped field" ) ; 
34-                         } 
35-                         default_fn = Some ( fn_path) ; 
36-                     }  else  { 
37-                         bail ! ( "default attribute value must be a string literal" ) ; 
38-                     } 
3932                }  else  { 
4033                    unknown_attrs. push ( attr) ; 
4134                } 
@@ -55,6 +48,15 @@ impl Field {
5548            ) ; 
5649        } 
5750
51+         if  let  Some ( lit)  = default_lit { 
52+             let  fn_path:  Path  = syn:: parse_str ( & lit. value ( ) ) 
53+                 . map_err ( |_| anyhow:: anyhow!( "invalid path for default function" ) ) ?; 
54+             if  default_fn. is_some ( )  { 
55+                 bail ! ( "duplicate default attribute for skipped field" ) ; 
56+             } 
57+             default_fn = Some ( fn_path) ; 
58+         } 
59+ 
5860        Ok ( Some ( Field  {  default_fn } ) ) 
5961    } 
6062
@@ -70,4 +72,4 @@ impl Field {
7072            quote !  {  :: core:: default :: Default :: default ( )  } 
7173        } 
7274    } 
73- } 
75+ } 
0 commit comments