diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index 535219d187d..f765b1ae5b6 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -278,7 +278,9 @@ impl ToComputedValue for specified::CalcLengthOrPercentage { #[animate(fallback = "Self::animate_fallback")] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[css(derive_debug)] -#[derive(Animate, Clone, Copy, PartialEq, ToAnimatedZero, ToCss)] +#[derive(Animate, Clone, ComputeSquaredDistance, Copy, PartialEq)] +#[derive(ToAnimatedZero, ToCss)] +#[distance(fallback = "Self::compute_squared_distance_fallback")] pub enum LengthOrPercentage { Length(Au), Percentage(Percentage), @@ -304,22 +306,16 @@ impl LengthOrPercentage { let other = CalcLengthOrPercentage::from(*other); Ok(LengthOrPercentage::Calc(this.animate(&other, procedure)?)) } -} -impl ComputeSquaredDistance for LengthOrPercentage { #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&LengthOrPercentage::Length(ref this), &LengthOrPercentage::Length(ref other)) => { - this.compute_squared_distance(other) - }, - (&LengthOrPercentage::Percentage(ref this), &LengthOrPercentage::Percentage(ref other)) => { - this.compute_squared_distance(other) - }, - (this, other) => { - CalcLengthOrPercentage::compute_squared_distance(&(*this).into(), &(*other).into()) - } - } + fn compute_squared_distance_fallback( + &self, + other: &Self, + ) -> Result { + CalcLengthOrPercentage::compute_squared_distance( + &(*self).into(), + &(*other).into(), + ) } } @@ -432,7 +428,8 @@ impl ToComputedValue for specified::LengthOrPercentage { #[animate(fallback = "Self::animate_fallback")] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[css(derive_debug)] -#[derive(Animate, Clone, Copy, PartialEq, ToCss)] +#[derive(Animate, Clone, ComputeSquaredDistance, Copy, PartialEq, ToCss)] +#[distance(fallback = "Self::compute_squared_distance_fallback")] pub enum LengthOrPercentageOrAuto { Length(Au), Percentage(Percentage), @@ -453,22 +450,16 @@ impl LengthOrPercentageOrAuto { this.animate(&other, procedure)?.ok_or(())?, )) } -} -impl ComputeSquaredDistance for LengthOrPercentageOrAuto { #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&LengthOrPercentageOrAuto::Length(ref this), &LengthOrPercentageOrAuto::Length(ref other)) => { - this.compute_squared_distance(other) - }, - (&LengthOrPercentageOrAuto::Percentage(ref this), &LengthOrPercentageOrAuto::Percentage(ref other)) => { - this.compute_squared_distance(other) - }, - (this, other) => { - >::compute_squared_distance(&(*this).into(), &(*other).into()) - } - } + fn compute_squared_distance_fallback( + &self, + other: &Self, + ) -> Result { + >::compute_squared_distance( + &(*self).into(), + &(*other).into(), + ) } } @@ -533,7 +524,8 @@ impl ToComputedValue for specified::LengthOrPercentageOrAuto { #[animate(fallback = "Self::animate_fallback")] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[css(derive_debug)] -#[derive(Animate, Clone, Copy, PartialEq, ToCss)] +#[derive(Animate, Clone, ComputeSquaredDistance, Copy, PartialEq, ToCss)] +#[distance(fallback = "Self::compute_squared_distance_fallback")] pub enum LengthOrPercentageOrNone { Length(Au), Percentage(Percentage), @@ -554,22 +546,15 @@ impl LengthOrPercentageOrNone { this.animate(&other, procedure)?.ok_or(())?, )) } -} -impl ComputeSquaredDistance for LengthOrPercentageOrNone { - #[inline] - fn compute_squared_distance(&self, other: &Self) -> Result { - match (self, other) { - (&LengthOrPercentageOrNone::Length(ref this), &LengthOrPercentageOrNone::Length(ref other)) => { - this.compute_squared_distance(other) - }, - (&LengthOrPercentageOrNone::Percentage(ref this), &LengthOrPercentageOrNone::Percentage(ref other)) => { - this.compute_squared_distance(other) - }, - (this, other) => { - >::compute_squared_distance(&(*this).into(), &(*other).into()) - } - } + fn compute_squared_distance_fallback( + &self, + other: &Self, + ) -> Result { + >::compute_squared_distance( + &(*self).into(), + &(*other).into(), + ) } } diff --git a/components/style_derive/compute_squared_distance.rs b/components/style_derive/compute_squared_distance.rs index 0cc19d2d737..cbdd9c62acc 100644 --- a/components/style_derive/compute_squared_distance.rs +++ b/components/style_derive/compute_squared_distance.rs @@ -4,15 +4,16 @@ use animate::AnimationVariantAttrs; use cg; -use quote; -use syn; +use quote::Tokens; +use syn::{DeriveInput, Path}; -pub fn derive(input: syn::DeriveInput) -> quote::Tokens { +pub fn derive(input: DeriveInput) -> Tokens { let name = &input.ident; let trait_path = &["values", "distance", "ComputeSquaredDistance"]; let (impl_generics, ty_generics, mut where_clause) = cg::trait_parts(&input, trait_path); + let input_attrs = cg::parse_input_attrs::(&input); let variants = cg::variants(&input); let mut match_body = quote!(); let mut append_error_clause = variants.len() > 1; @@ -45,7 +46,13 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens { })); if append_error_clause { - match_body = quote! { #match_body, _ => Err(()), }; + if let Some(fallback) = input_attrs.fallback { + match_body.append(quote! { + (this, other) => #fallback(this, other) + }); + } else { + match_body.append(quote! { _ => Err(()) }); + } } quote! { @@ -63,3 +70,9 @@ pub fn derive(input: syn::DeriveInput) -> quote::Tokens { } } } + +#[darling(attributes(distance), default)] +#[derive(Default, FromDeriveInput)] +struct DistanceInputAttrs { + fallback: Option, +} diff --git a/components/style_derive/lib.rs b/components/style_derive/lib.rs index a0e09477c57..f98829e60bf 100644 --- a/components/style_derive/lib.rs +++ b/components/style_derive/lib.rs @@ -25,7 +25,7 @@ pub fn derive_animate(stream: TokenStream) -> TokenStream { animate::derive(input).to_string().parse().unwrap() } -#[proc_macro_derive(ComputeSquaredDistance, attributes(animation))] +#[proc_macro_derive(ComputeSquaredDistance, attributes(animation, distance))] 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()