Skip to content

Commit

Permalink
Syn examples recommend keeping the span of the fields you're iteratin…
Browse files Browse the repository at this point in the history
…g over, so I copied how the heapsize example does it.
  • Loading branch information
adamchalmers committed Dec 20, 2023
1 parent 7006a31 commit 97026a6
Showing 1 changed file with 28 additions and 14 deletions.
42 changes: 28 additions & 14 deletions execution-plan-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,33 @@ fn impl_value_on_struct(
// For every field in the struct, this macro will:
// - In the `into_parts`, extend the Vec of parts with that field, turned into parts.
// - In the `from_parts`, instantiate a Self with a field from that part.
let field_names: Vec<_> = fields.named.iter().filter_map(|field| field.ident.as_ref()).collect();
let mut extend_per_field = quote!();
let mut instantiate_each_field = quote!();
for field in field_names {
extend_per_field = quote! {
parts.extend(self.#field.into_parts());
#extend_per_field
};
instantiate_each_field = quote! {
#field: kittycad_execution_plan_traits::Value::from_parts(values)?,
#instantiate_each_field
let field_names: Vec<_> =
fields
.named
.iter()
.filter_map(|field| {
if let Some(id) = field.ident.as_ref() {
Some((id, field.span()))
} else {
None
}
})
.collect();
// We take some care to use the span of each `syn::Field` as
// the span of the corresponding `into_parts()` and `from_parts()`
// calls. This way if one of the field types does not
// implement `Value` then the compiler's error message
// underlines which field it is.
let extend_per_field = field_names.iter().map(|(ident, span)| {
quote_spanned! {*span=>
parts.extend(self.#ident.into_parts());
}
}
});
let instantiate_each_field = field_names.iter().map(|(ident, span)| {
quote_spanned! {*span=>
#ident: kittycad_execution_plan_traits::Value::from_parts(values)?,
}
});

// Handle generics in the original struct.
// Firstly, if the original struct has defaults on its generics, e.g. Point2d<T = f32>,
Expand All @@ -79,7 +93,7 @@ fn impl_value_on_struct(
{
fn into_parts(self) -> Vec<kittycad_execution_plan_traits::Primitive> {
let mut parts = Vec::new();
#extend_per_field
#(#extend_per_field)*
parts
}

Expand All @@ -88,7 +102,7 @@ fn impl_value_on_struct(
I: Iterator<Item = Option<kittycad_execution_plan_traits::Primitive>>,
{
Ok(Self {
#instantiate_each_field
#(#instantiate_each_field)*
})
}
}
Expand Down

0 comments on commit 97026a6

Please sign in to comment.