@@ -3,7 +3,9 @@ use quote::{quote, quote_spanned};
33use  syn:: punctuated:: Punctuated ; 
44use  syn:: spanned:: Spanned ; 
55use  syn:: token:: Comma ; 
6- use  syn:: { Attribute ,  DeriveInput ,  Field ,  Lit ,  Meta ,  MetaNameValue ,  NestedMeta ,  Variant } ; 
6+ use  syn:: { 
7+     Attribute ,  DeriveInput ,  Expr ,  Field ,  Lit ,  LitStr ,  Meta ,  MetaNameValue ,  Path ,  Token ,  Variant , 
8+ } ; 
79
810macro_rules!  assert_attribute { 
911    ( $e: expr,  $err: expr,  $input: expr)  => { 
@@ -83,89 +85,94 @@ pub fn parse_container_attributes(input: &[Attribute]) -> syn::Result<SqlxContai
8385
8486    for  attr in  input
8587        . iter ( ) 
86-         . filter ( |a| a. path . is_ident ( "sqlx" )  || a. path . is_ident ( "repr" ) ) 
88+         . filter ( |a| a. path ( ) . is_ident ( "sqlx" )  || a. path ( ) . is_ident ( "repr" ) ) 
8789    { 
88-         let  meta = attr
89-             . parse_meta ( ) 
90-             . map_err ( |e| syn:: Error :: new_spanned ( attr,  e) ) ?; 
91-         match  meta { 
90+         match  & attr. meta  { 
9291            Meta :: List ( list)  if  list. path . is_ident ( "sqlx" )  => { 
93-                 for  value in  list. nested . iter ( )  { 
94-                     match  value { 
95-                         NestedMeta :: Meta ( meta)  => match  meta { 
96-                             Meta :: Path ( p)  if  p. is_ident ( "transparent" )  => { 
97-                                 try_set ! ( transparent,  true ,  value) 
92+                 let  nested_metas =
93+                     list. parse_args_with ( Punctuated :: < Meta ,  syn:: token:: Comma > :: parse_terminated) ?; 
94+                 for  meta_item in  nested_metas { 
95+                     match  meta_item { 
96+                         Meta :: Path ( p)  if  p. is_ident ( "transparent" )  => { 
97+                             try_set ! ( transparent,  true ,  p) 
98+                         } 
99+                         Meta :: NameValue ( mnv)  if  mnv. path . is_ident ( "rename_all" )  => { 
100+                             if  let  Expr :: Lit ( expr_lit)  = & mnv. value  { 
101+                                 if  let  Lit :: Str ( val_str)  = & expr_lit. lit  { 
102+                                     let  val = match  & * val_str. value ( )  { 
103+                                         "lowercase"  => RenameAll :: LowerCase , 
104+                                         "snake_case"  => RenameAll :: SnakeCase , 
105+                                         "UPPERCASE"  => RenameAll :: UpperCase , 
106+                                         "SCREAMING_SNAKE_CASE"  => RenameAll :: ScreamingSnakeCase , 
107+                                         "kebab-case"  => RenameAll :: KebabCase , 
108+                                         "camelCase"  => RenameAll :: CamelCase , 
109+                                         "PascalCase"  => RenameAll :: PascalCase , 
110+                                         _ => fail ! ( val_str,  "unexpected value for rename_all" ) , 
111+                                     } ; 
112+                                     try_set ! ( rename_all,  val,  & mnv. path) 
113+                                 }  else  { 
114+                                     fail ! ( expr_lit,  "expected string literal for rename_all" ) 
115+                                 } 
116+                             }  else  { 
117+                                 fail ! ( & mnv. value,  "expected literal expression for rename_all" ) 
98118                            } 
99- 
100-                              Meta :: NameValue ( MetaNameValue  { 
101-                                 path , 
102-                                 lit :   Lit :: Str ( val ) , 
103-                                 .. 
104-                             } )   if  path . is_ident ( "rename_all" )  =>  { 
105-                                 let  val =  match   & * val . value ( )  { 
106-                                     "lowercase"  =>  RenameAll :: LowerCase , 
107-                                     "snake_case"  =>  RenameAll :: SnakeCase , 
108-                                     "UPPERCASE"  =>  RenameAll :: UpperCase , 
109-                                     "SCREAMING_SNAKE_CASE"  =>  RenameAll :: ScreamingSnakeCase , 
110-                                     "kebab-case"  =>  RenameAll :: KebabCase , 
111-                                     "camelCase"  =>  RenameAll :: CamelCase , 
112-                                      "PascalCase"  =>  RenameAll :: PascalCase , 
113-                                     _ =>  fail ! ( meta ,  "unexpected value  for rename_all"  ) , 
114-                                 } ; 
115- 
116-                                 try_set ! ( rename_all ,  val ,  value ) 
119+                          } 
120+                         Meta :: NameValue ( mnv )   if  mnv . path . is_ident ( "type_name" )  =>  { 
121+                             if   let   Expr :: Lit ( expr_lit )  =  & mnv . value   { 
122+                                 if   let   Lit :: Str ( val_str )  =  & expr_lit . lit   { 
123+                                      try_set ! ( 
124+                                         type_name , 
125+                                          TypeName  { 
126+                                             val :  val_str . value ( ) , 
127+                                             span :  val_str . span ( ) , 
128+                                             deprecated_rename :   false 
129+                                          } , 
130+                                          & mnv . path 
131+                                     ) 
132+                                 }   else   { 
133+                                     fail ! ( expr_lit ,  "expected string literal  for type_name"  ) 
134+                                 } 
135+                              }   else   { 
136+                                 fail ! ( & mnv . value ,   "expected literal expression for type_name" ) 
117137                            } 
118- 
119-                             Meta :: NameValue ( MetaNameValue  { 
120-                                 path, 
121-                                 lit :  Lit :: Str ( val) , 
122-                                 ..
123-                             } )  if  path. is_ident ( "type_name" )  => { 
124-                                 try_set ! ( 
125-                                     type_name, 
126-                                     TypeName  { 
127-                                         val:  val. value( ) , 
128-                                         span:  value. span( ) , 
129-                                         deprecated_rename:  false 
130-                                     } , 
131-                                     value
132-                                 ) 
138+                         } 
139+                         Meta :: NameValue ( mnv)  if  mnv. path . is_ident ( "rename" )  => { 
140+                             if  let  Expr :: Lit ( expr_lit)  = & mnv. value  { 
141+                                 if  let  Lit :: Str ( val_str)  = & expr_lit. lit  { 
142+                                     try_set ! ( 
143+                                         type_name, 
144+                                         TypeName  { 
145+                                             val:  val_str. value( ) , 
146+                                             span:  val_str. span( ) , 
147+                                             deprecated_rename:  true 
148+                                         } , 
149+                                         & mnv. path
150+                                     ) 
151+                                 }  else  { 
152+                                     fail ! ( expr_lit,  "expected string literal for rename" ) 
153+                                 } 
154+                             }  else  { 
155+                                 fail ! ( & mnv. value,  "expected literal expression for rename" ) 
133156                            } 
134- 
135-                             Meta :: NameValue ( MetaNameValue  { 
136-                                 path, 
137-                                 lit :  Lit :: Str ( val) , 
138-                                 ..
139-                             } )  if  path. is_ident ( "rename" )  => { 
140-                                 try_set ! ( 
141-                                     type_name, 
142-                                     TypeName  { 
143-                                         val:  val. value( ) , 
144-                                         span:  value. span( ) , 
145-                                         deprecated_rename:  true 
146-                                     } , 
147-                                     value
148-                                 ) 
149-                             } 
150- 
151-                             u => fail ! ( u,  "unexpected attribute" ) , 
152-                         } , 
153-                         u => fail ! ( u,  "unexpected attribute" ) , 
157+                         } 
158+                         u => fail ! ( u,  "unexpected attribute inside sqlx(...)" ) , 
154159                    } 
155160                } 
156161            } 
157162            Meta :: List ( list)  if  list. path . is_ident ( "repr" )  => { 
158-                 if  list. nested . len ( )  != 1  { 
159-                     fail ! ( & list. nested,  "expected one value" ) 
163+                 let  nested_metas =
164+                     list. parse_args_with ( Punctuated :: < Meta ,  syn:: token:: Comma > :: parse_terminated) ?; 
165+                 if  nested_metas. len ( )  != 1  { 
166+                     fail ! ( & list. path,  "expected one value for repr" ) 
160167                } 
161-                 match  list . nested . first ( ) . unwrap ( )  { 
162-                     NestedMeta :: Meta ( Meta :: Path ( p) )  if  p. get_ident ( ) . is_some ( )  => { 
163-                         try_set ! ( repr,  p. get_ident( ) . unwrap( ) . clone( ) ,  list) ; 
168+                 match  nested_metas . first ( ) . unwrap ( )  { 
169+                     Meta :: Path ( p)  if  p. get_ident ( ) . is_some ( )  => { 
170+                         try_set ! ( repr,  p. get_ident( ) . unwrap( ) . clone( ) ,  & list. path ) ; 
164171                    } 
165-                     u => fail ! ( u,  "unexpected value" ) , 
172+                     u => fail ! ( u,  "unexpected value for repr " ) , 
166173                } 
167174            } 
168-             _ => { } 
175+             _ => {   /* Not an attribute we are interested in, or not a list */   } 
169176        } 
170177    } 
171178
@@ -183,30 +190,37 @@ pub fn parse_child_attributes(input: &[Attribute]) -> syn::Result<SqlxChildAttri
183190    let  mut  try_from = None ; 
184191    let  mut  flatten = false ; 
185192
186-     for  attr in  input. iter ( ) . filter ( |a| a. path . is_ident ( "sqlx" ) )  { 
187-         let  meta = attr
188-             . parse_meta ( ) 
189-             . map_err ( |e| syn:: Error :: new_spanned ( attr,  e) ) ?; 
190- 
191-         if  let  Meta :: List ( list)  = meta { 
192-             for  value in  list. nested . iter ( )  { 
193-                 match  value { 
194-                     NestedMeta :: Meta ( meta)  => match  meta { 
195-                         Meta :: NameValue ( MetaNameValue  { 
196-                             path, 
197-                             lit :  Lit :: Str ( val) , 
198-                             ..
199-                         } )  if  path. is_ident ( "rename" )  => try_set ! ( rename,  val. value( ) ,  value) , 
200-                         Meta :: NameValue ( MetaNameValue  { 
201-                             path, 
202-                             lit :  Lit :: Str ( val) , 
203-                             ..
204-                         } )  if  path. is_ident ( "try_from" )  => try_set ! ( try_from,  val. parse( ) ?,  value) , 
205-                         Meta :: Path ( path)  if  path. is_ident ( "default" )  => default = true , 
206-                         Meta :: Path ( path)  if  path. is_ident ( "flatten" )  => flatten = true , 
207-                         u => fail ! ( u,  "unexpected attribute" ) , 
208-                     } , 
209-                     u => fail ! ( u,  "unexpected attribute" ) , 
193+     for  attr in  input. iter ( ) . filter ( |a| a. path ( ) . is_ident ( "sqlx" ) )  { 
194+         if  let  Meta :: List ( list)  = & attr. meta  { 
195+             let  nested_metas =
196+                 list. parse_args_with ( Punctuated :: < Meta ,  syn:: token:: Comma > :: parse_terminated) ?; 
197+             for  meta_item in  nested_metas { 
198+                 match  meta_item { 
199+                     Meta :: NameValue ( mnv)  if  mnv. path . is_ident ( "rename" )  => { 
200+                         if  let  Expr :: Lit ( expr_lit)  = & mnv. value  { 
201+                             if  let  Lit :: Str ( val_str)  = & expr_lit. lit  { 
202+                                 try_set ! ( rename,  val_str. value( ) ,  & mnv. path) 
203+                             }  else  { 
204+                                 fail ! ( expr_lit,  "expected string literal for rename" ) 
205+                             } 
206+                         }  else  { 
207+                             fail ! ( & mnv. value,  "expected literal expression for rename" ) 
208+                         } 
209+                     } 
210+                     Meta :: NameValue ( mnv)  if  mnv. path . is_ident ( "try_from" )  => { 
211+                         if  let  Expr :: Lit ( expr_lit)  = & mnv. value  { 
212+                             if  let  Lit :: Str ( val_str)  = & expr_lit. lit  { 
213+                                 try_set ! ( try_from,  val_str. parse( ) ?,  & mnv. path) 
214+                             }  else  { 
215+                                 fail ! ( expr_lit,  "expected string literal for try_from" ) 
216+                             } 
217+                         }  else  { 
218+                             fail ! ( & mnv. value,  "expected literal expression for try_from" ) 
219+                         } 
220+                     } 
221+                     Meta :: Path ( path)  if  path. is_ident ( "default" )  => default = true , 
222+                     Meta :: Path ( path)  if  path. is_ident ( "flatten" )  => flatten = true , 
223+                     u => fail ! ( u,  "unexpected attribute inside sqlx(...)" ) , 
210224                } 
211225            } 
212226        } 
0 commit comments