Skip to content

Commit

Permalink
Fix IntoParts implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
adamchalmers committed Dec 21, 2023
1 parent 7b126a8 commit 62d13b9
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 35 deletions.
2 changes: 1 addition & 1 deletion execution-plan-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ authors = ["Adam Chalmers"]
[dependencies]
proc-macro2 = "1.0.70"
quote = "1.0.33"
syn = "2.0.41"
syn = { version = "2.0.41", features = ["extra-traits"] }

[lib]
proc-macro = true
Expand Down
42 changes: 33 additions & 9 deletions execution-plan-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ fn impl_value_on_enum(
#name::#variant_name{#(#field_idents),*}
},
quote_spanned! {expr.span()=>
vec![
Primitive::from(stringify!(#variant_name).to_owned()),
#(Primitive::from(#field_idents),)*
]
let mut parts = Vec::new();
parts.push(kittycad_execution_plan_traits::Primitive::from(stringify!(#variant_name).to_owned()));
#(parts.extend(#field_idents.into_parts());)*
parts
},
)
}
Expand All @@ -76,10 +76,10 @@ fn impl_value_on_enum(
#name::#variant_name(#(#placeholder_field_idents),*)
},
quote_spanned! {expr.span() =>
vec![
Primitive::from(stringify!(#variant_name).to_owned()),
#(Primitive::from(#placeholder_field_idents),)*
]
let mut parts = Vec::new();
parts.push(kittycad_execution_plan_traits::Primitive::from(stringify!(#variant_name).to_owned()));
#(parts.extend(#placeholder_field_idents.into_parts());)*
parts
},
)
}
Expand Down Expand Up @@ -113,7 +113,7 @@ fn impl_value_on_enum(
let (field_idents, field_types): (Vec<_>, Vec<_>) = expr
.named
.iter()
.filter_map(|named| named.ident.as_ref().map(|id| (id, &named.ty)))
.filter_map(|named| named.ident.as_ref().map(|id| (id, remove_generics(named.ty.clone()))))
.unzip();
let rhs = quote_spanned! {expr.span()=>
#(let #field_idents = #field_types::from_parts(values)?;)*
Expand Down Expand Up @@ -195,6 +195,17 @@ fn impl_value_on_enum(
}
}

fn remove_generics(mut ty: syn::Type) -> syn::Type {
if let syn::Type::Path(ref mut p) = ty {
for segment in p.path.segments.iter_mut() {
if let syn::PathArguments::AngleBracketed(ref mut _a) = segment.arguments {
segment.arguments = syn::PathArguments::None;
}
}
}
ty
}

fn impl_value_on_struct(
span: Span,
name: proc_macro2::Ident,
Expand Down Expand Up @@ -299,6 +310,19 @@ mod tests {
insta::assert_snapshot!(formatted);
}

#[test]
fn test_enum_with_generics() {
let input = quote! {
enum Segment {
Line { point: Point3d<f64> }
}
};
let input: DeriveInput = syn::parse2(input).unwrap();
let out = impl_derive_value(input);
let formatted = get_text_fmt(&out).unwrap();
insta::assert_snapshot!(formatted);
}

fn clean_text(s: &str) -> String {
// Add newlines after end-braces at <= two levels of indentation.
if cfg!(not(windows)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ impl kittycad_execution_plan_traits::Value for FooEnum {
fn into_parts(self) -> Vec<kittycad_execution_plan_traits::Primitive> {
match self {
FooEnum::A { x } => {
vec![
Primitive::from(stringify!(A).to_owned()),
Primitive::from(x),
]
let mut parts = Vec::new();
parts . push (kittycad_execution_plan_traits :: Primitive :: from (stringify ! (A) . to_owned ())) ;
parts.extend(x.into_parts());
parts
}
FooEnum::B { y } => {
vec![
Primitive::from(stringify!(B).to_owned()),
Primitive::from(y),
]
let mut parts = Vec::new();
parts . push (kittycad_execution_plan_traits :: Primitive :: from (stringify ! (B) . to_owned ())) ;
parts.extend(y.into_parts());
parts
}
FooEnum::C(field0, field1) => {
vec![
Primitive::from(stringify!(C).to_owned()),
Primitive::from(field0),
Primitive::from(field1),
]
let mut parts = Vec::new();
parts . push (kittycad_execution_plan_traits :: Primitive :: from (stringify ! (C) . to_owned ())) ;
parts.extend(field0.into_parts());
parts.extend(field1.into_parts());
parts
}
FooEnum::D => Vec::new(),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
source: execution-plan-macros/src/lib.rs
expression: formatted
---
impl kittycad_execution_plan_traits::Value for Segment {
fn into_parts(self) -> Vec<kittycad_execution_plan_traits::Primitive> {
match self {
Segment::Line { point } => {
let mut parts = Vec::new();
parts.push(
kittycad_execution_plan_traits::Primitive::from(stringify!(Line).to_owned())
);
parts.extend(point.into_parts());
parts
}
}
}

fn from_parts<I>(values: &mut I) -> Result<Self, kittycad_execution_plan_traits::MemoryError>
where
I: Iterator<Item = Option<kittycad_execution_plan_traits::Primitive>>,
{
let variant_name = String::from_parts(values)?;
match variant_name.as_str() {
stringify!(Line) => {
let point = Point3d::from_parts(values)?;
Ok(Self::Line { point })
}
other => Err(
kittycad_execution_plan_traits::MemoryError::InvalidEnumVariant {
expected_type: stringify!(Segment).to_owned(),
actual: other.to_owned(),
},
),
}
}
}

28 changes: 16 additions & 12 deletions execution-plan-macros/tests/main.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
use kittycad_execution_plan_macros::ExecutionPlanValue;
use kittycad_execution_plan_traits::{Primitive, Value};

#[derive(ExecutionPlanValue)]
struct FooGenericWithDefault<T = f32>
where
Primitive: From<T>,
T: Value,
{
f: f64,
i: usize,
t: T,
}

#[derive(ExecutionPlanValue)]
struct FooConcrete {
Expand All @@ -25,3 +13,19 @@ enum FooEnum {
C(usize, String, f64, f32),
D,
}

mod generics {
use kittycad_execution_plan_macros::ExecutionPlanValue;
use kittycad_execution_plan_traits::{Primitive, Value};

#[derive(ExecutionPlanValue)]
struct FooGenericWithDefault<T = f32>
where
Primitive: From<T>,
T: Value,
{
f: f64,
i: usize,
t: T,
}
}

0 comments on commit 62d13b9

Please sign in to comment.