From ff67fc751d8e1df9ee0c08199bc87501fb99ae5c Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Thu, 24 Aug 2017 01:25:57 +0200 Subject: [PATCH] Introduce #[animation] For now, only #[animation(error)] is supported on variants and it makes both #[derive(Animate)] and #[derive(ComputeSquaredDistance)] ignore this particular variant. --- .../helpers/animated_properties.mako.rs | 34 ------------------- .../style/properties/longhand/box.mako.rs | 5 +-- components/style_derive/animate.rs | 20 ++++++++--- .../style_derive/compute_squared_distance.rs | 13 +++++-- components/style_derive/lib.rs | 4 +-- 5 files changed, 31 insertions(+), 45 deletions(-) diff --git a/components/style/properties/helpers/animated_properties.mako.rs b/components/style/properties/helpers/animated_properties.mako.rs index 02a60d209b1..2f7aaafc63d 100644 --- a/components/style/properties/helpers/animated_properties.mako.rs +++ b/components/style/properties/helpers/animated_properties.mako.rs @@ -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 { - 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 { - 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 { Err(()) } diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 659d8c69307..ae22a94dc4f 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -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), } diff --git a/components/style_derive/animate.rs b/components/style_derive/animate.rs index 888a5e61c8e..94d14336087 100644 --- a/components/style_derive/animate.rs +++ b/components/style_derive/animate.rs @@ -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::(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, +} diff --git a/components/style_derive/compute_squared_distance.rs b/components/style_derive/compute_squared_distance.rs index df02d1312cc..860e568ea88 100644 --- a/components/style_derive/compute_squared_distance.rs +++ b/components/style_derive/compute_squared_distance.rs @@ -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::(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(()), }; } diff --git a/components/style_derive/lib.rs b/components/style_derive/lib.rs index b49b4597315..e589759f813 100644 --- a/components/style_derive/lib.rs +++ b/components/style_derive/lib.rs @@ -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()