1
1
use std:: convert:: { TryFrom , TryInto } ;
2
2
3
- use syn:: { Attribute , Error , Ident , Lit , Meta , MetaNameValue , NestedMeta } ;
3
+ use syn:: spanned:: Spanned ;
4
+ use syn:: { Attribute , Error , Expr , ExprLit , Ident , Lit , LitStr , Meta } ;
4
5
5
6
use crate :: { error:: ErrorMsg , iden_path:: IdenPath } ;
6
7
@@ -14,8 +15,13 @@ pub(crate) enum IdenAttr {
14
15
impl IdenAttr {
15
16
fn extract_method ( meta : Meta ) -> syn:: Result < Self > {
16
17
match meta {
17
- Meta :: NameValue ( nv) => match nv. lit {
18
- Lit :: Str ( name) => Ok ( Self :: Method ( Ident :: new ( name. value ( ) . as_str ( ) , name. span ( ) ) ) ) ,
18
+ Meta :: NameValue ( nv) => match nv. value {
19
+ Expr :: Lit ( ExprLit { lit, .. } ) => match lit {
20
+ Lit :: Str ( name) => {
21
+ Ok ( Self :: Method ( Ident :: new ( name. value ( ) . as_str ( ) , name. span ( ) ) ) )
22
+ }
23
+ _ => Err ( Error :: new_spanned ( nv. eq_token , ErrorMsg :: WrongLiteral ) ) ,
24
+ } ,
19
25
_ => Err ( Error :: new_spanned ( nv, ErrorMsg :: WrongLiteral ) ) ,
20
26
} ,
21
27
a => Err ( Error :: new_spanned (
@@ -27,37 +33,39 @@ impl IdenAttr {
27
33
28
34
fn extract_iden ( meta : Meta ) -> syn:: Result < Self > {
29
35
match & meta {
30
- Meta :: NameValue ( nv) => match & nv. lit {
31
- Lit :: Str ( lit) => Ok ( IdenAttr :: Rename ( lit. value ( ) ) ) ,
32
- _ => Err ( Error :: new_spanned ( & nv. lit , ErrorMsg :: WrongLiteral ) ) ,
33
- } ,
34
- Meta :: List ( list) => match list. nested . first ( ) {
35
- Some ( NestedMeta :: Meta ( Meta :: Path ( p) ) ) if p. is_ident ( & IdenPath :: Flatten ) => {
36
- Ok ( IdenAttr :: Flatten )
37
- }
38
- Some ( NestedMeta :: Meta ( Meta :: NameValue ( nv) ) ) => Self :: extract_named_value_iden ( nv) ,
39
- _ => Err ( Error :: new_spanned ( meta, ErrorMsg :: WrongListFormat ) ) ,
36
+ Meta :: NameValue ( nv) => match & nv. value {
37
+ Expr :: Lit ( ExprLit { lit, .. } ) => match lit {
38
+ Lit :: Str ( lit) => Ok ( IdenAttr :: Rename ( lit. value ( ) ) ) ,
39
+ _ => Err ( Error :: new_spanned ( & nv. value , ErrorMsg :: WrongLiteral ) ) ,
40
+ } ,
41
+ _ => Err ( Error :: new_spanned ( nv, ErrorMsg :: WrongLiteral ) ) ,
40
42
} ,
41
- a => Err ( Error :: new_spanned ( a, ErrorMsg :: WrongAttributeFormat ) ) ,
42
- }
43
- }
44
-
45
- fn extract_named_value_iden ( nv : & MetaNameValue ) -> syn:: Result < Self > {
46
- match & nv. lit {
47
- Lit :: Str ( name) => {
48
- // Don't match "iden" since that would mean `#[iden(iden = "name")]` would be accepted
49
- if nv. path . is_ident ( & IdenPath :: Rename ) {
50
- Ok ( Self :: Rename ( name. value ( ) ) )
51
- } else if nv. path . is_ident ( & IdenPath :: Method ) {
52
- Ok ( Self :: Method ( Ident :: new ( name. value ( ) . as_str ( ) , name. span ( ) ) ) )
53
- } else {
54
- Err ( Error :: new_spanned (
55
- nv,
56
- ErrorMsg :: UnsupportedKeyword ( nv. path . get_ident ( ) . unwrap ( ) . clone ( ) ) ,
57
- ) )
58
- }
43
+ Meta :: List ( list) if list. path . is_ident ( "iden" ) => {
44
+ let mut iden_attr: Option < Self > = None ;
45
+ list. parse_nested_meta ( |nested| {
46
+ if nested. path . is_ident ( & IdenPath :: Flatten ) {
47
+ iden_attr = Some ( IdenAttr :: Flatten ) ;
48
+ Ok ( ( ) )
49
+ } else if nested. path . is_ident ( & IdenPath :: Rename ) {
50
+ let value = nested. value ( ) ?;
51
+ let value: LitStr = value. parse ( ) ?;
52
+ iden_attr = Some ( IdenAttr :: Rename ( value. value ( ) ) ) ;
53
+ Ok ( ( ) )
54
+ } else if nested. path . is_ident ( & IdenPath :: Method ) {
55
+ let value = nested. value ( ) ?;
56
+ let value: LitStr = value. parse ( ) ?;
57
+ iden_attr = Some ( IdenAttr :: Method ( Ident :: new ( & value. value ( ) , meta. span ( ) ) ) ) ;
58
+ Ok ( ( ) )
59
+ } else {
60
+ Err ( Error :: new_spanned (
61
+ & meta,
62
+ ErrorMsg :: UnsupportedKeyword ( nested. path . get_ident ( ) . unwrap ( ) . clone ( ) ) ,
63
+ ) )
64
+ }
65
+ } ) ?;
66
+ iden_attr. ok_or ( Error :: new_spanned ( meta, ErrorMsg :: WrongListFormat ) )
59
67
}
60
- _ => Err ( Error :: new_spanned ( & nv . lit , ErrorMsg :: WrongLiteral ) ) ,
68
+ a => Err ( Error :: new_spanned ( a , ErrorMsg :: WrongAttributeFormat ) ) ,
61
69
}
62
70
}
63
71
}
@@ -66,7 +74,7 @@ impl TryFrom<&Attribute> for IdenAttr {
66
74
type Error = Error ;
67
75
68
76
fn try_from ( value : & Attribute ) -> Result < Self , Self :: Error > {
69
- value. parse_meta ( ) ? . try_into ( )
77
+ value. meta . clone ( ) . try_into ( )
70
78
}
71
79
}
72
80
0 commit comments