1
1
use proc_macro2:: Span ;
2
+ use quote:: ToTokens ;
2
3
use syn:: meta:: ParseNestedMeta ;
3
4
use syn:: parse:: { Error , Parse , ParseStream , Result } ;
4
5
use syn:: { Data , DeriveInput , Fields , Generics , Ident , LitInt , LitStr , Token } ;
@@ -92,6 +93,37 @@ impl Parse for Input {
92
93
}
93
94
}
94
95
96
+ fn parse_field < T : ToTokens + Copy > ( span : T , i : usize , field : & syn:: Field ) -> Result < Field > {
97
+ let ident = field
98
+ . ident
99
+ . as_ref ( )
100
+ . ok_or_else ( || Error :: new_spanned ( span, "Tuple structs are not supported" ) ) ?;
101
+ let mut skip_serializing_if = None ;
102
+ for attr in & field. attrs {
103
+ if attr. path ( ) . is_ident ( "serde" ) {
104
+ attr. parse_nested_meta ( |meta| {
105
+ if meta. path . is_ident ( "skip_serializing_if" ) {
106
+ let litstr: LitStr = meta. value ( ) ?. parse ( ) ?;
107
+ let tokens = syn:: parse_str ( & litstr. value ( ) ) ?;
108
+ if skip_serializing_if. is_some ( ) {
109
+ return Err ( meta. error ( "Multiple attributes for skip_serializing_if" ) ) ;
110
+ }
111
+ skip_serializing_if = Some ( syn:: parse2 ( tokens) ?) ;
112
+ Ok ( ( ) )
113
+ } else {
114
+ Err ( meta. error ( "Unkown field attribute" ) )
115
+ }
116
+ } ) ?;
117
+ }
118
+ }
119
+ Ok ( Field {
120
+ label : ident. to_string ( ) ,
121
+ member : syn:: Member :: Named ( ident. clone ( ) ) ,
122
+ index : i,
123
+ skip_serializing_if,
124
+ } )
125
+ }
126
+
95
127
fn fields_from_ast (
96
128
attrs : & StructAttrs ,
97
129
fields : & syn:: punctuated:: Punctuated < syn:: Field , Token ! [ , ] > ,
@@ -107,46 +139,6 @@ fn fields_from_ast(
107
139
fields
108
140
. iter ( )
109
141
. enumerate ( )
110
- . map ( |( i, field) | {
111
- Ok ( Field {
112
- // these are https://docs.rs/syn/2.0.28/syn/struct.Field.html
113
- label : match & field. ident {
114
- Some ( ident) => ident. to_string ( ) ,
115
- None => {
116
- return Err ( Error :: new_spanned ( fields, "Tuple struct are not supported" ) ) ;
117
- }
118
- } ,
119
- member : match & field. ident {
120
- Some ( ident) => syn:: Member :: Named ( ident. clone ( ) ) ,
121
- None => {
122
- return Err ( Error :: new_spanned ( fields, "Tuple struct are not supported" ) ) ;
123
- }
124
- } ,
125
- index : i,
126
- // TODO: make this... more concise? handle errors? the thing with the spans?
127
- skip_serializing_if : {
128
- let mut skip_serializing_if = None ;
129
- for attr in & field. attrs {
130
- if attr. path ( ) . is_ident ( "serde" ) {
131
- attr. parse_nested_meta ( |meta| {
132
- if meta. path . is_ident ( "skip_serializing_if" ) {
133
- let litstr: LitStr = meta. value ( ) ?. parse ( ) ?;
134
- let tokens = syn:: parse_str ( & litstr. value ( ) ) ?;
135
- if skip_serializing_if. is_some ( ) {
136
- return Err ( meta
137
- . error ( "Multiple attributes for skip_serializing_if" ) ) ;
138
- }
139
- skip_serializing_if = Some ( syn:: parse2 ( tokens) ?) ;
140
- Ok ( ( ) )
141
- } else {
142
- Err ( meta. error ( "Unkown field attribute" ) )
143
- }
144
- } ) ?;
145
- }
146
- }
147
- skip_serializing_if
148
- } ,
149
- } )
150
- } )
142
+ . map ( |( i, field) | parse_field ( fields, i, field) )
151
143
. collect ( )
152
144
}
0 commit comments