@@ -3,7 +3,7 @@ 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:: { Attribute , DeriveInput , Field , Lit , Meta , MetaNameValue , Variant , Expr , LitStr , Token , Path } ;
77
88macro_rules! assert_attribute {
99 ( $e: expr, $err: expr, $input: expr) => {
@@ -83,89 +83,92 @@ pub fn parse_container_attributes(input: &[Attribute]) -> syn::Result<SqlxContai
8383
8484 for attr in input
8585 . iter ( )
86- . filter ( |a| a. path . is_ident ( "sqlx" ) || a. path . is_ident ( "repr" ) )
86+ . filter ( |a| a. path ( ) . is_ident ( "sqlx" ) || a. path ( ) . is_ident ( "repr" ) )
8787 {
88- let meta = attr
89- . parse_meta ( )
90- . map_err ( |e| syn:: Error :: new_spanned ( attr, e) ) ?;
91- match meta {
88+ match & attr. meta {
9289 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)
90+ let nested_metas = list. parse_args_with ( Punctuated :: < Meta , syn:: token:: Comma > :: parse_terminated) ?;
91+ for meta_item in nested_metas {
92+ match meta_item {
93+ Meta :: Path ( p) if p. is_ident ( "transparent" ) => {
94+ try_set ! ( transparent, true , p)
95+ }
96+ Meta :: NameValue ( mnv) if mnv. path . is_ident ( "rename_all" ) => {
97+ if let Expr :: Lit ( expr_lit) = & mnv. value {
98+ if let Lit :: Str ( val_str) = & expr_lit. lit {
99+ let val = match & * val_str. value ( ) {
100+ "lowercase" => RenameAll :: LowerCase ,
101+ "snake_case" => RenameAll :: SnakeCase ,
102+ "UPPERCASE" => RenameAll :: UpperCase ,
103+ "SCREAMING_SNAKE_CASE" => RenameAll :: ScreamingSnakeCase ,
104+ "kebab-case" => RenameAll :: KebabCase ,
105+ "camelCase" => RenameAll :: CamelCase ,
106+ "PascalCase" => RenameAll :: PascalCase ,
107+ _ => fail ! ( val_str, "unexpected value for rename_all" ) ,
108+ } ;
109+ try_set ! ( rename_all, val, & mnv. path)
110+ } else {
111+ fail ! ( expr_lit, "expected string literal for rename_all" )
112+ }
113+ } else {
114+ fail ! ( & mnv. value, "expected literal expression for rename_all" )
98115 }
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 )
116+ }
117+ Meta :: NameValue ( mnv ) if mnv . path . is_ident ( "type_name" ) => {
118+ if let Expr :: Lit ( expr_lit ) = & mnv . value {
119+ if let Lit :: Str ( val_str ) = & expr_lit . lit {
120+ try_set ! (
121+ type_name ,
122+ TypeName {
123+ val : val_str . value ( ) ,
124+ span : val_str . span ( ) ,
125+ deprecated_rename : false
126+ } ,
127+ & mnv . path
128+ )
129+ } else {
130+ fail ! ( expr_lit , "expected string literal for type_name" )
131+ }
132+ } else {
133+ fail ! ( & mnv . value , "expected literal expression for type_name" )
117134 }
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- )
135+ }
136+ Meta :: NameValue ( mnv) if mnv. path . is_ident ( "rename" ) => {
137+ if let Expr :: Lit ( expr_lit) = & mnv. value {
138+ if let Lit :: Str ( val_str) = & expr_lit. lit {
139+ try_set ! (
140+ type_name,
141+ TypeName {
142+ val: val_str. value( ) ,
143+ span: val_str. span( ) ,
144+ deprecated_rename: true
145+ } ,
146+ & mnv. path
147+ )
148+ } else {
149+ fail ! ( expr_lit, "expected string literal for rename" )
150+ }
151+ } else {
152+ fail ! ( & mnv. value, "expected literal expression for rename" )
133153 }
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" ) ,
154+ }
155+ u => fail ! ( u, "unexpected attribute inside sqlx(...)" ) ,
154156 }
155157 }
156158 }
157159 Meta :: List ( list) if list. path . is_ident ( "repr" ) => {
158- if list. nested . len ( ) != 1 {
159- fail ! ( & list. nested, "expected one value" )
160+ let nested_metas = list. parse_args_with ( Punctuated :: < Meta , syn:: token:: Comma > :: parse_terminated) ?;
161+ if nested_metas. len ( ) != 1 {
162+ fail ! ( & list. path, "expected one value for repr" )
160163 }
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) ;
164+ match nested_metas . first ( ) . unwrap ( ) {
165+ Meta :: Path ( p) if p. get_ident ( ) . is_some ( ) => {
166+ try_set ! ( repr, p. get_ident( ) . unwrap( ) . clone( ) , & list. path ) ;
164167 }
165- u => fail ! ( u, "unexpected value" ) ,
168+ u => fail ! ( u, "unexpected value for repr " ) ,
166169 }
167170 }
168- _ => { }
171+ _ => { /* Not an attribute we are interested in, or not a list */ }
169172 }
170173 }
171174
@@ -183,30 +186,36 @@ pub fn parse_child_attributes(input: &[Attribute]) -> syn::Result<SqlxChildAttri
183186 let mut try_from = None ;
184187 let mut flatten = false ;
185188
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" ) ,
189+ for attr in input. iter ( ) . filter ( |a| a. path ( ) . is_ident ( "sqlx" ) ) {
190+ if let Meta :: List ( list) = & attr. meta {
191+ let nested_metas = list. parse_args_with ( Punctuated :: < Meta , syn:: token:: Comma > :: parse_terminated) ?;
192+ for meta_item in nested_metas {
193+ match meta_item {
194+ Meta :: NameValue ( mnv) if mnv. path . is_ident ( "rename" ) => {
195+ if let Expr :: Lit ( expr_lit) = & mnv. value {
196+ if let Lit :: Str ( val_str) = & expr_lit. lit {
197+ try_set ! ( rename, val_str. value( ) , & mnv. path)
198+ } else {
199+ fail ! ( expr_lit, "expected string literal for rename" )
200+ }
201+ } else {
202+ fail ! ( & mnv. value, "expected literal expression for rename" )
203+ }
204+ }
205+ Meta :: NameValue ( mnv) if mnv. path . is_ident ( "try_from" ) => {
206+ if let Expr :: Lit ( expr_lit) = & mnv. value {
207+ if let Lit :: Str ( val_str) = & expr_lit. lit {
208+ try_set ! ( try_from, val_str. parse( ) ?, & mnv. path)
209+ } else {
210+ fail ! ( expr_lit, "expected string literal for try_from" )
211+ }
212+ } else {
213+ fail ! ( & mnv. value, "expected literal expression for try_from" )
214+ }
215+ }
216+ Meta :: Path ( path) if path. is_ident ( "default" ) => default = true ,
217+ Meta :: Path ( path) if path. is_ident ( "flatten" ) => flatten = true ,
218+ u => fail ! ( u, "unexpected attribute inside sqlx(...)" ) ,
210219 }
211220 }
212221 }
0 commit comments