@@ -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