@@ -3,7 +3,9 @@ use quote::{quote, quote_spanned};
3
3
use syn:: punctuated:: Punctuated ;
4
4
use syn:: spanned:: Spanned ;
5
5
use 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
+ } ;
7
9
8
10
macro_rules! assert_attribute {
9
11
( $e: expr, $err: expr, $input: expr) => {
@@ -83,89 +85,94 @@ pub fn parse_container_attributes(input: &[Attribute]) -> syn::Result<SqlxContai
83
85
84
86
for attr in input
85
87
. 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" ) )
87
89
{
88
- let meta = attr
89
- . parse_meta ( )
90
- . map_err ( |e| syn:: Error :: new_spanned ( attr, e) ) ?;
91
- match meta {
90
+ match & attr. meta {
92
91
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" )
98
118
}
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" )
117
137
}
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" )
133
156
}
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(...)" ) ,
154
159
}
155
160
}
156
161
}
157
162
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" )
160
167
}
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 ) ;
164
171
}
165
- u => fail ! ( u, "unexpected value" ) ,
172
+ u => fail ! ( u, "unexpected value for repr " ) ,
166
173
}
167
174
}
168
- _ => { }
175
+ _ => { /* Not an attribute we are interested in, or not a list */ }
169
176
}
170
177
}
171
178
@@ -183,30 +190,37 @@ pub fn parse_child_attributes(input: &[Attribute]) -> syn::Result<SqlxChildAttri
183
190
let mut try_from = None ;
184
191
let mut flatten = false ;
185
192
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(...)" ) ,
210
224
}
211
225
}
212
226
}
0 commit comments