Introduce #[animation]

For now, only #[animation(error)] is supported on variants and it makes
both #[derive(Animate)] and #[derive(ComputeSquaredDistance)] ignore
this particular variant.
This commit is contained in:
Anthony Ramine 2017-08-24 01:25:57 +02:00
parent 17d97cf87b
commit ff67fc751d
5 changed files with 31 additions and 45 deletions

View file

@ -787,40 +787,6 @@ impl ToAnimatedZero for Visibility {
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-length
impl Animate for VerticalAlign {
#[inline]
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
match (self, other) {
(
&VerticalAlign::LengthOrPercentage(ref this),
&VerticalAlign::LengthOrPercentage(ref other),
) => {
Ok(VerticalAlign::LengthOrPercentage(
this.animate(other, procedure)?
))
},
_ => Err(()),
}
}
}
impl ComputeSquaredDistance for VerticalAlign {
#[inline]
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
match (self, other) {
(&VerticalAlign::LengthOrPercentage(ref this), &VerticalAlign::LengthOrPercentage(ref other)) => {
this.compute_squared_distance(other)
},
_ => {
// FIXME(nox): Should this return `Ok(SquaredDistance::Value(0.))`
// if `self` and `other` are the same keyword value?
Err(())
},
}
}
}
impl ToAnimatedZero for VerticalAlign {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> { Err(()) }

View file

@ -370,11 +370,12 @@ ${helpers.single_keyword("position", "static absolute relative fixed",
/// The keywords are the same, and the `LengthOrPercentage` is computed
/// here.
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, PartialEq)]
pub enum T {
% for keyword in vertical_align_keywords:
${to_rust_ident(keyword)},
#[animation(error)] // only animatable as a length
${to_rust_ident(keyword)},
% endfor
LengthOrPercentage(computed::LengthOrPercentage),
}

View file

@ -14,7 +14,13 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
let variants = cg::variants(&input);
let mut match_body = quote!();
match_body.append_all(variants.iter().map(|variant| {
let mut append_error_clause = variants.len() > 1;
match_body.append_all(variants.iter().flat_map(|variant| {
let attrs = cg::parse_variant_attrs::<AnimateAttrs>(variant);
if attrs.error {
append_error_clause = true;
return None;
}
let name = cg::variant_ctor(&input, variant);
let (this_pattern, this_info) = cg::ref_pattern(&name, variant, "this");
let (other_pattern, other_info) = cg::ref_pattern(&name, variant, "other");
@ -29,15 +35,15 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
let #result = ::values::animated::Animate::animate(#this, #other, procedure)?;
}
}));
quote! {
Some(quote! {
(&#this_pattern, &#other_pattern) => {
#computations
Ok(#result_value)
}
}
})
}));
if variants.len() > 1 {
if append_error_clause {
match_body = quote! { #match_body, _ => Err(()), };
}
@ -57,3 +63,9 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
}
}
}
#[derive(Default, FromVariant)]
#[darling(attributes(animate), default)]
pub struct AnimateAttrs {
pub error: bool,
}

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use animate::AnimateAttrs;
use cg;
use quote;
use syn;
@ -14,7 +15,13 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
let variants = cg::variants(&input);
let mut match_body = quote!();
let mut append_error_clause = variants.len() > 1;
match_body.append_all(variants.iter().map(|variant| {
let attrs = cg::parse_variant_attrs::<AnimateAttrs>(variant);
if attrs.error {
append_error_clause = true;
return None;
}
let name = cg::variant_ctor(&input, variant);
let (this_pattern, this_info) = cg::ref_pattern(&name, &variant, "this");
let (other_pattern, other_info) = cg::ref_pattern(&name, &variant, "other");
@ -32,14 +39,14 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
}), "+");
sum
};
quote! {
Some(quote! {
(&#this_pattern, &#other_pattern) => {
Ok(#sum)
}
}
})
}));
if variants.len() > 1 {
if append_error_clause {
match_body = quote! { #match_body, _ => Err(()), };
}

View file

@ -19,13 +19,13 @@ mod to_animated_zero;
mod to_computed_value;
mod to_css;
#[proc_macro_derive(Animate)]
#[proc_macro_derive(Animate, attributes(animation))]
pub fn derive_animate(stream: TokenStream) -> TokenStream {
let input = syn::parse_derive_input(&stream.to_string()).unwrap();
animate::derive(input).to_string().parse().unwrap()
}
#[proc_macro_derive(ComputeSquaredDistance)]
#[proc_macro_derive(ComputeSquaredDistance, attributes(animation))]
pub fn derive_compute_squared_distance(stream: TokenStream) -> TokenStream {
let input = syn::parse_derive_input(&stream.to_string()).unwrap();
compute_squared_distance::derive(input).to_string().parse().unwrap()