Implement #[compute(clone)] for #[derive(ToComputedValue)]

This commit is contained in:
Anthony Ramine 2017-08-26 12:56:50 +02:00
parent efc852f6e3
commit 735e093de7
6 changed files with 37 additions and 95 deletions

View file

@ -49,7 +49,7 @@ pub fn derive_to_animated_zero(stream: TokenStream) -> TokenStream {
to_animated_zero::derive(input).to_string().parse().unwrap()
}
#[proc_macro_derive(ToComputedValue)]
#[proc_macro_derive(ToComputedValue, attributes(compute))]
pub fn derive_to_computed_value(stream: TokenStream) -> TokenStream {
let input = syn::parse_derive_input(&stream.to_string()).unwrap();
to_computed_value::derive(input).to_string().parse().unwrap()

View file

@ -14,14 +14,31 @@ pub fn derive(input: DeriveInput) -> Tokens {
cg::fmap_trait_parts(&input, trait_path, "ComputedValue");
let to_body = cg::fmap_match(&input, BindStyle::Ref, |binding| {
where_clause.add_trait_bound(&binding.field.ty);
quote! {
::values::computed::ToComputedValue::to_computed_value(#binding, context)
let attrs = cg::parse_field_attrs::<ComputedValueAttrs>(&binding.field);
if attrs.clone {
if cg::is_parameterized(&binding.field.ty, where_clause.params, None) {
where_clause.inner.predicates.push(cg::where_predicate(
binding.field.ty.clone(),
&["std", "clone", "Clone"],
None,
));
}
quote! { ::std::clone::Clone::clone(#binding) }
} else {
where_clause.add_trait_bound(&binding.field.ty);
quote! {
::values::computed::ToComputedValue::to_computed_value(#binding, context)
}
}
});
let from_body = cg::fmap_match(&input, BindStyle::Ref, |binding| {
quote! {
::values::computed::ToComputedValue::from_computed_value(#binding)
let attrs = cg::parse_field_attrs::<ComputedValueAttrs>(&binding.field);
if attrs.clone {
quote! { ::std::clone::Clone::clone(#binding) }
} else {
quote! {
::values::computed::ToComputedValue::from_computed_value(#binding)
}
}
});
@ -46,3 +63,9 @@ pub fn derive(input: DeriveInput) -> Tokens {
}
}
}
#[darling(attributes(compute), default)]
#[derive(Default, FromField)]
struct ComputedValueAttrs {
clone: bool,
}