@@ -113,7 +113,12 @@ impl Parse for Input {
113113 }
114114}
115115
116- fn parse_field ( index : usize , field : & syn:: Field ) -> Result < Field > {
116+ fn parse_field (
117+ attrs : & StructAttrs ,
118+ auto_index : usize ,
119+ field : & syn:: Field ,
120+ indices : & mut Vec < usize > ,
121+ ) -> Result < Field > {
117122 let ident = field
118123 . ident
119124 . as_ref ( )
@@ -123,6 +128,7 @@ fn parse_field(index: usize, field: &syn::Field) -> Result<Field> {
123128 let mut deserialize_with = None ;
124129 let mut serialize_with = None ;
125130 let mut no_increment = false ;
131+ let mut explicit_index = None ;
126132
127133 for attr in & field. attrs {
128134 if attr. path ( ) . is_ident ( "serde" ) {
@@ -191,6 +197,22 @@ fn parse_field(index: usize, field: &syn::Field) -> Result<Field> {
191197 serialize_with = Some ( syn:: parse2 ( serialize_tokens) ?) ;
192198 deserialize_with = Some ( syn:: parse2 ( deserialize_tokens) ?) ;
193199
200+ Ok ( ( ) )
201+ } else if meta. path . is_ident ( "index" ) {
202+ if explicit_index. is_some ( ) {
203+ return Err ( meta. error ( "Multiple attributes for index" ) ) ;
204+ }
205+ if attrs. auto_index {
206+ return Err ( meta. error (
207+ "The index attribute cannot be combined with the auto_index attribute" ,
208+ ) ) ;
209+ }
210+ let litint: LitInt = meta. value ( ) ?. parse ( ) ?;
211+ let int = litint. base10_parse ( ) ?;
212+ if indices. contains ( & int) {
213+ return Err ( meta. error ( "This index has already been assigned" ) ) ;
214+ }
215+ explicit_index = Some ( int) ;
194216 Ok ( ( ) )
195217 } else {
196218 return Err ( meta. error ( "Unkown field attribute" ) ) ;
@@ -199,6 +221,17 @@ fn parse_field(index: usize, field: &syn::Field) -> Result<Field> {
199221 }
200222 }
201223
224+ let index = if attrs. auto_index {
225+ auto_index
226+ } else if let Some ( index) = explicit_index {
227+ indices. push ( index) ;
228+ index
229+ } else {
230+ return Err ( Error :: new_spanned (
231+ field,
232+ "Field without index attribute and `#[serde(auto_index)]` is not enabled on the struct" ,
233+ ) ) ;
234+ } ;
202235 Ok ( Field {
203236 label : ident. to_string ( ) ,
204237 member : syn:: Member :: Named ( ident. clone ( ) ) ,
@@ -216,18 +249,12 @@ fn fields_from_ast(
216249 attrs : & StructAttrs ,
217250 fields : & syn:: punctuated:: Punctuated < syn:: Field , Token ! [ , ] > ,
218251) -> Result < Vec < Field > > {
219- if !attrs. auto_index {
220- return Err ( Error :: new_spanned (
221- fields,
222- "auto_index attribute must be set" ,
223- ) ) ;
224- }
225-
252+ let mut indices = Vec :: new ( ) ;
226253 let mut index = 0 ;
227254 fields
228255 . iter ( )
229256 . map ( |field| {
230- let field = parse_field ( index, field) ?;
257+ let field = parse_field ( attrs , index, field, & mut indices ) ?;
231258 if !field. no_increment {
232259 index += 1 ;
233260 }
0 commit comments