Skip to content

Commit dd10343

Browse files
committed
Directly use tuple indexing with numbers.
1 parent c04bfbc commit dd10343

File tree

1 file changed

+93
-36
lines changed
  • crates/serialize_hierarchy_derive/src

1 file changed

+93
-36
lines changed

crates/serialize_hierarchy_derive/src/lib.rs

+93-36
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::HashSet;
22

3-
use proc_macro2::{Span, TokenStream};
3+
use proc_macro2::{Literal, TokenStream};
44
use proc_macro_error::{abort, proc_macro_error};
55
use quote::{quote, ToTokens};
66
use syn::{
@@ -165,52 +165,91 @@ fn generate_path_serializations(fields: &[&Field]) -> Vec<TokenStream> {
165165
fields
166166
.iter()
167167
.filter(|field| !field.attributes.contains(&FieldAttribute::Leaf))
168-
.map(|field| {
169-
let identifier = &field.identifier;
170-
let pattern = identifier.to_string();
171-
quote! {
172-
#pattern => self.#identifier.serialize_path(suffix, serializer)
168+
.map(|field| match &field.identifier {
169+
IdentOrEnumIndex::Ident(identifier) => {
170+
let pattern = identifier.to_string();
171+
quote! {
172+
#pattern => self.#identifier.serialize_path(suffix, serializer)
173+
}
174+
}
175+
IdentOrEnumIndex::EnumIndex(index) => {
176+
let pattern = index.to_string();
177+
let tuple_accessor = Literal::usize_unsuffixed(*index);
178+
quote! {
179+
#pattern => self.#tuple_accessor.serialize_path(suffix, serializer)
180+
}
173181
}
174182
})
175183
.collect()
176184
}
177185

178186
fn generate_serde_serializations(fields: &[&Field]) -> Vec<TokenStream> {
179-
fields.iter().map(|field| {
180-
let identifier = &field.identifier;
181-
let pattern = identifier.to_string();
182-
quote! {
183-
#pattern => serde::Serialize::serialize(&self.#identifier, serializer).map_err(serialize_hierarchy::Error::SerializationFailed)
184-
}
187+
fields.iter().map(|field|
188+
match &field.identifier {
189+
IdentOrEnumIndex::Ident(identifier) => {
190+
let pattern = identifier.to_string();
191+
quote! {
192+
#pattern => serde::Serialize::serialize(&self.#identifier, serializer).map_err(serialize_hierarchy::Error::SerializationFailed)
193+
}
194+
},
195+
IdentOrEnumIndex::EnumIndex(index) =>{
196+
let pattern = index.to_string();
197+
let tuple_accessor = Literal::usize_unsuffixed(*index);
198+
quote! {
199+
#pattern => serde::Serialize::serialize(&self.#tuple_accessor, serializer).map_err(serialize_hierarchy::Error::SerializationFailed)
200+
}
201+
},
185202
}).collect()
186203
}
187204

188205
fn generate_path_deserializations(fields: &[&Field]) -> Vec<TokenStream> {
189206
fields
190207
.iter()
191208
.filter(|field| !field.attributes.contains(&FieldAttribute::Leaf))
192-
.map(|field| {
193-
let identifier = &field.identifier;
194-
let pattern = identifier.to_string();
195-
quote! {
196-
#pattern => self.#identifier.deserialize_path(suffix, deserializer)
209+
.map(|field| match &field.identifier {
210+
IdentOrEnumIndex::Ident(identifier) => {
211+
let pattern = identifier.to_string();
212+
quote! {
213+
#pattern => self.#identifier.deserialize_path(suffix, deserializer)
214+
}
215+
}
216+
IdentOrEnumIndex::EnumIndex(index) => {
217+
let pattern = index.to_string();
218+
let tuple_accessor = Literal::usize_unsuffixed(*index);
219+
quote! {
220+
#pattern => self.#tuple_accessor.deserialize_path(suffix, deserializer)
221+
}
197222
}
198223
})
199224
.collect()
200225
}
201226

202227
fn generate_serde_deserializations(fields: &[&Field]) -> Vec<TokenStream> {
203-
fields.iter().map(|field| {
204-
let identifier = &field.identifier;
205-
let pattern = identifier.to_string();
206-
let ty = &field.ty;
207-
quote! {
208-
#pattern => {
209-
self.#identifier = <#ty as serde::Deserialize>::deserialize(deserializer).map_err(serialize_hierarchy::Error::DeserializationFailed)?;
210-
Ok(())
211-
}
228+
fields.iter().map(|field|
229+
match &field.identifier {
230+
IdentOrEnumIndex::Ident(identifier) => {
231+
let pattern = identifier.to_string();
232+
let ty = &field.ty;
233+
quote! {
234+
#pattern => {
235+
self.#identifier = <#ty as serde::Deserialize>::deserialize(deserializer).map_err(serialize_hierarchy::Error::DeserializationFailed)?;
236+
Ok(())
237+
}
212238

213-
}
239+
}
240+
},
241+
IdentOrEnumIndex::EnumIndex(index) => {
242+
let pattern = index.to_string();
243+
let tuple_accessor = Literal::usize_unsuffixed(*index);
244+
let ty = &field.ty;
245+
quote! {
246+
#pattern => {
247+
self.#tuple_accessor = <#ty as serde::Deserialize>::deserialize(deserializer).map_err(serialize_hierarchy::Error::DeserializationFailed)?;
248+
Ok(())
249+
}
250+
251+
}
252+
}
214253
}).collect()
215254
}
216255

@@ -219,7 +258,10 @@ fn generate_path_exists_getters(fields: &[&Field]) -> Vec<TokenStream> {
219258
.iter()
220259
.filter(|field| !field.attributes.contains(&FieldAttribute::Leaf))
221260
.map(|field| {
222-
let pattern = field.identifier.to_string();
261+
let pattern = match &field.identifier {
262+
IdentOrEnumIndex::Ident(identifier) => identifier.to_string(),
263+
IdentOrEnumIndex::EnumIndex(index) => index.to_string(),
264+
};
223265
let ty = &field.ty;
224266
quote! {
225267
#pattern => <#ty as serialize_hierarchy::SerializeHierarchy>::exists(suffix)
@@ -232,7 +274,10 @@ fn generate_field_exists_getters(fields: &[&Field]) -> Vec<TokenStream> {
232274
fields
233275
.iter()
234276
.map(|field| {
235-
let pattern = field.identifier.to_string();
277+
let pattern = match &field.identifier {
278+
IdentOrEnumIndex::Ident(identifier) => identifier.to_string(),
279+
IdentOrEnumIndex::EnumIndex(index) => index.to_string(),
280+
};
236281
quote! {
237282
#pattern => true
238283
}
@@ -244,7 +289,10 @@ fn generate_field_chains(fields: &[&Field]) -> Vec<TokenStream> {
244289
fields
245290
.iter()
246291
.map(|field| {
247-
let name_string = field.identifier.to_string();
292+
let name_string = match &field.identifier {
293+
IdentOrEnumIndex::Ident(identifier) => identifier.to_string(),
294+
IdentOrEnumIndex::EnumIndex(index) => index.to_string(),
295+
};
248296
quote! {
249297
fields.insert(format!("{prefix}{}", #name_string));
250298
}
@@ -257,7 +305,10 @@ fn generate_path_field_chains(fields: &[&Field]) -> Vec<TokenStream> {
257305
.iter()
258306
.filter(|field| !field.attributes.contains(&FieldAttribute::Leaf))
259307
.map(|field| {
260-
let field_name = &field.identifier.to_string();
308+
let field_name = match &field.identifier {
309+
IdentOrEnumIndex::Ident(identifier) => identifier.to_string(),
310+
IdentOrEnumIndex::EnumIndex(index)=>index.to_string(),
311+
};
261312
let ty = &field.ty;
262313
quote! {
263314
<#ty as serialize_hierarchy::SerializeHierarchy>::fill_fields(fields, &format!("{prefix}{}.", #field_name));
@@ -319,10 +370,16 @@ enum FieldAttribute {
319370
Leaf,
320371
}
321372

373+
#[derive(Debug)]
374+
enum IdentOrEnumIndex {
375+
Ident(Ident),
376+
EnumIndex(usize),
377+
}
378+
322379
#[derive(Debug)]
323380
struct Field {
324381
attributes: HashSet<FieldAttribute>,
325-
identifier: Ident,
382+
identifier: IdentOrEnumIndex,
326383
ty: Type,
327384
}
328385

@@ -368,10 +425,10 @@ fn read_fields(input: &DataStruct) -> Vec<Field> {
368425
}
369426
})
370427
.collect();
371-
let identifier = field
372-
.ident
373-
.clone()
374-
.unwrap_or(Ident::new(&format!("_{}", field_index), Span::call_site()));
428+
let identifier = field.ident.clone().map_or_else(
429+
|| IdentOrEnumIndex::EnumIndex(field_index),
430+
|identifier| IdentOrEnumIndex::Ident(identifier),
431+
);
375432
let ty = field.ty.clone();
376433
Field {
377434
attributes,

0 commit comments

Comments
 (0)