Derive the most trivial ToAnimatedZero impls

This commit is contained in:
Anthony Ramine 2017-08-22 15:30:43 +02:00
parent 8ca9542de6
commit faaf31411a
15 changed files with 112 additions and 174 deletions

View file

@ -84,7 +84,7 @@ macro_rules! define_keyword_type {
($name: ident, $css: expr) => { ($name: ident, $css: expr) => {
#[allow(missing_docs)] #[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, ComputeSquaredDistance, Copy, PartialEq, ToCss)] #[derive(Clone, ComputeSquaredDistance, Copy, PartialEq, ToAnimatedZero, ToCss)]
pub struct $name; pub struct $name;
impl $crate::values::animated::Animate for $name { impl $crate::values::animated::Animate for $name {
@ -115,10 +115,5 @@ macro_rules! define_keyword_type {
impl $crate::values::computed::ComputedValueAsSpecified for $name {} impl $crate::values::computed::ComputedValueAsSpecified for $name {}
impl $crate::values::animated::AnimatedValueAsComputed for $name {} impl $crate::values::animated::AnimatedValueAsComputed for $name {}
no_viewport_percentage!($name); no_viewport_percentage!($name);
impl $crate::values::animated::ToAnimatedZero for $name {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> { Ok($name) }
}
}; };
} }

View file

@ -879,23 +879,6 @@ impl Animate for LengthOrPercentage {
} }
} }
impl ToAnimatedZero for LengthOrPercentage {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
match *self {
LengthOrPercentage::Length(ref length) => {
Ok(LengthOrPercentage::Length(length.to_animated_zero()?))
},
LengthOrPercentage::Percentage(ref percentage) => {
Ok(LengthOrPercentage::Percentage(percentage.to_animated_zero()?))
},
LengthOrPercentage::Calc(ref calc) => {
Ok(LengthOrPercentage::Calc(calc.to_animated_zero()?))
},
}
}
}
/// https://drafts.csswg.org/css-transitions/#animtype-lpcalc /// https://drafts.csswg.org/css-transitions/#animtype-lpcalc
impl Animate for LengthOrPercentageOrAuto { impl Animate for LengthOrPercentageOrAuto {
#[inline] #[inline]
@ -1134,20 +1117,6 @@ where
} }
} }
impl<H, V> ToAnimatedZero for generic_position::Position<H, V>
where
H: ToAnimatedZero,
V: ToAnimatedZero,
{
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
Ok(generic_position::Position {
horizontal: self.horizontal.to_animated_zero()?,
vertical: self.vertical.to_animated_zero()?,
})
}
}
impl<H, V> RepeatableListAnimatable for generic_position::Position<H, V> impl<H, V> RepeatableListAnimatable for generic_position::Position<H, V>
where H: RepeatableListAnimatable, V: RepeatableListAnimatable {} where H: RepeatableListAnimatable, V: RepeatableListAnimatable {}
@ -2689,28 +2658,6 @@ where
} }
} }
impl<L, N> ToAnimatedZero for SvgLengthOrPercentageOrNumber<L, N>
where
L: ToAnimatedZero,
N: ToAnimatedZero,
{
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
match *self {
SvgLengthOrPercentageOrNumber::LengthOrPercentage(ref lop) => {
Ok(SvgLengthOrPercentageOrNumber::LengthOrPercentage(
lop.to_animated_zero()?,
))
},
SvgLengthOrPercentageOrNumber::Number(ref num) => {
Ok(SvgLengthOrPercentageOrNumber::Number(
num.to_animated_zero()?,
))
},
}
}
}
impl<L> Animate for SVGLength<L> impl<L> Animate for SVGLength<L>
where where
L: Animate + Clone, L: Animate + Clone,
@ -2732,21 +2679,6 @@ where
} }
} }
impl<L> ToAnimatedZero for SVGLength<L>
where
L: ToAnimatedZero,
{
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
match *self {
SVGLength::Length(ref length) => {
Ok(SVGLength::Length(length.to_animated_zero()?))
},
SVGLength::ContextValue => Ok(SVGLength::ContextValue),
}
}
}
/// https://www.w3.org/TR/SVG11/painting.html#StrokeDasharrayProperty /// https://www.w3.org/TR/SVG11/painting.html#StrokeDasharrayProperty
impl<L> Animate for SVGStrokeDashArray<L> impl<L> Animate for SVGStrokeDashArray<L>
where where
@ -2772,7 +2704,7 @@ where
impl<L> ToAnimatedZero for SVGStrokeDashArray<L> impl<L> ToAnimatedZero for SVGStrokeDashArray<L>
where where
L: Clone + ToAnimatedZero L: ToAnimatedZero,
{ {
#[inline] #[inline]
fn to_animated_zero(&self) -> Result<Self, ()> { fn to_animated_zero(&self) -> Result<Self, ()> {
@ -2808,19 +2740,6 @@ where
} }
} }
impl<OpacityType> ToAnimatedZero for SVGOpacity<OpacityType>
where OpacityType: ToAnimatedZero + Clone
{
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
match self {
&SVGOpacity::Opacity(ref opacity) =>
opacity.to_animated_zero().map(SVGOpacity::Opacity),
other => Ok(other.clone()),
}
}
}
<% <%
FILTER_FUNCTIONS = [ 'Blur', 'Brightness', 'Contrast', 'Grayscale', FILTER_FUNCTIONS = [ 'Blur', 'Brightness', 'Contrast', 'Grayscale',
'HueRotate', 'Invert', 'Opacity', 'Saturate', 'HueRotate', 'Invert', 'Opacity', 'Saturate',
@ -2877,7 +2796,6 @@ impl ToAnimatedZero for AnimatedFilter {
} }
} }
// FIXME(nox): This should be derived. // FIXME(nox): This should be derived.
impl ComputeSquaredDistance for AnimatedFilter { impl ComputeSquaredDistance for AnimatedFilter {
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {
@ -3004,15 +2922,6 @@ where
} }
} }
impl<T> ToAnimatedZero for NonNegative<T>
where T: ToAnimatedZero
{
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
self.0.to_animated_zero().map(NonNegative::<T>)
}
}
impl<T> Animate for GreaterThanOrEqualToOne<T> impl<T> Animate for GreaterThanOrEqualToOne<T>
where where
T: Animate, T: Animate,
@ -3022,12 +2931,3 @@ where
Ok(GreaterThanOrEqualToOne(self.0.animate(&other.0, procedure)?)) Ok(GreaterThanOrEqualToOne(self.0.animate(&other.0, procedure)?))
} }
} }
impl<T> ToAnimatedZero for GreaterThanOrEqualToOne<T>
where T: ToAnimatedZero
{
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
self.0.to_animated_zero().map(GreaterThanOrEqualToOne::<T>)
}
}

View file

@ -12,7 +12,7 @@ use values::distance::{ComputeSquaredDistance, SquaredDistance};
/// Unlike in computed values, each component value may exceed the /// Unlike in computed values, each component value may exceed the
/// range `[0.0, 1.0]`. /// range `[0.0, 1.0]`.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq, ToAnimatedZero)]
pub struct RGBA { pub struct RGBA {
/// The red component. /// The red component.
pub red: f32, pub red: f32,
@ -69,13 +69,6 @@ impl ComputeSquaredDistance for RGBA {
} }
} }
impl ToAnimatedZero for RGBA {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
Ok(RGBA::transparent())
}
}
#[allow(missing_docs)] #[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]

View file

@ -223,15 +223,3 @@ impl Animate for SimpleShadow {
}) })
} }
} }
impl ToAnimatedZero for SimpleShadow {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
Ok(SimpleShadow {
color: self.color.to_animated_zero()?,
horizontal: self.horizontal.to_animated_zero()?,
vertical: self.vertical.to_animated_zero()?,
blur: self.blur.to_animated_zero()?,
})
}
}

View file

@ -8,12 +8,12 @@ use std::{f32, f64, fmt};
use std::f64::consts::PI; use std::f64::consts::PI;
use style_traits::ToCss; use style_traits::ToCss;
use values::CSSFloat; use values::CSSFloat;
use values::animated::{Animate, Procedure, ToAnimatedZero}; use values::animated::{Animate, Procedure};
use values::distance::{ComputeSquaredDistance, SquaredDistance}; use values::distance::{ComputeSquaredDistance, SquaredDistance};
/// A computed angle. /// A computed angle.
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))] #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd)] #[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, PartialOrd, ToAnimatedZero)]
pub enum Angle { pub enum Angle {
/// An angle with degree unit. /// An angle with degree unit.
Degree(CSSFloat), Degree(CSSFloat),
@ -85,18 +85,6 @@ impl Animate for Angle {
} }
} }
impl ToAnimatedZero for Angle {
#[inline]
fn to_animated_zero(&self) -> Result<Angle, ()> {
match *self {
Angle::Degree(ref this) => Ok(Angle::Degree(this.to_animated_zero()?)),
Angle::Gradian(ref this) => Ok(Angle::Gradian(this.to_animated_zero()?)),
Angle::Radian(ref this) => Ok(Angle::Radian(this.to_animated_zero()?)),
Angle::Turn(ref this) => Ok(Angle::Turn(this.to_animated_zero()?)),
}
}
}
impl ComputeSquaredDistance for Angle { impl ComputeSquaredDistance for Angle {
#[inline] #[inline]
fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> {

View file

@ -286,7 +286,7 @@ impl ToComputedValue for specified::CalcLengthOrPercentage {
#[allow(missing_docs)] #[allow(missing_docs)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, PartialEq, ToCss)] #[derive(Clone, Copy, PartialEq, ToAnimatedZero, ToCss)]
pub enum LengthOrPercentage { pub enum LengthOrPercentage {
Length(Au), Length(Au),
Percentage(Percentage), Percentage(Percentage),

View file

@ -7,11 +7,12 @@
use std::fmt; use std::fmt;
use style_traits::ToCss; use style_traits::ToCss;
use values::{CSSFloat, serialize_percentage}; use values::{CSSFloat, serialize_percentage};
use values::animated::{Animate, Procedure, ToAnimatedZero}; use values::animated::{Animate, Procedure};
/// A computed percentage. /// A computed percentage.
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Default, HasViewportPercentage, PartialEq, PartialOrd)]
#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] #[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))]
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, Default)]
#[derive(HasViewportPercentage, PartialEq, PartialOrd, ToAnimatedZero)]
pub struct Percentage(pub CSSFloat); pub struct Percentage(pub CSSFloat);
impl Percentage { impl Percentage {
@ -42,13 +43,6 @@ impl Animate for Percentage {
} }
} }
impl ToAnimatedZero for Percentage {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
Ok(Percentage(0.))
}
}
impl ToCss for Percentage { impl ToCss for Percentage {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where where

View file

@ -4,7 +4,7 @@
//! Computed types for CSS values that are related to transformations. //! Computed types for CSS values that are related to transformations.
use values::animated::{Animate, Procedure, ToAnimatedZero}; use values::animated::{Animate, Procedure};
use values::computed::{Length, LengthOrPercentage, Number, Percentage}; use values::computed::{Length, LengthOrPercentage, Number, Percentage};
use values::generics::transform::TimingFunction as GenericTimingFunction; use values::generics::transform::TimingFunction as GenericTimingFunction;
use values::generics::transform::TransformOrigin as GenericTransformOrigin; use values::generics::transform::TransformOrigin as GenericTransformOrigin;
@ -37,14 +37,3 @@ impl Animate for TransformOrigin {
)) ))
} }
} }
impl ToAnimatedZero for TransformOrigin {
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
Ok(Self::new(
self.horizontal.to_animated_zero()?,
self.vertical.to_animated_zero()?,
self.depth.to_animated_zero()?,
))
}
}

View file

@ -65,7 +65,8 @@ pub enum Filter<Angle, Factor, Length, DropShadow> {
/// Contrary to the canonical order from the spec, the color is serialised /// Contrary to the canonical order from the spec, the color is serialised
/// first, like in Gecko and Webkit. /// first, like in Gecko and Webkit.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, ComputeSquaredDistance, Debug, HasViewportPercentage, PartialEq, ToAnimatedValue, ToCss)] #[derive(Clone, ComputeSquaredDistance, Debug, HasViewportPercentage, PartialEq)]
#[derive(ToAnimatedValue, ToAnimatedZero, ToCss)]
pub struct SimpleShadow<Color, SizeLength, ShapeLength> { pub struct SimpleShadow<Color, SizeLength, ShapeLength> {
/// Color. /// Color.
pub color: Color, pub color: Color,

View file

@ -269,11 +269,11 @@ impl ToCss for FontSettingTagFloat {
/// A wrapper of Non-negative values. /// A wrapper of Non-negative values.
#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] #[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))]
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage)] #[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage)]
#[derive(PartialEq, PartialOrd, ToComputedValue, ToCss)] #[derive(PartialEq, PartialOrd, ToAnimatedZero, ToComputedValue, ToCss)]
pub struct NonNegative<T>(pub T); pub struct NonNegative<T>(pub T);
/// A wrapper of greater-than-or-equal-to-one values. /// A wrapper of greater-than-or-equal-to-one values.
#[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))] #[cfg_attr(feature = "servo", derive(Deserialize, HeapSizeOf, Serialize))]
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage)] #[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage)]
#[derive(PartialEq, PartialOrd, ToComputedValue, ToCss)] #[derive(PartialEq, PartialOrd, ToAnimatedZero, ToComputedValue, ToCss)]
pub struct GreaterThanOrEqualToOne<T>(pub T); pub struct GreaterThanOrEqualToOne<T>(pub T);

View file

@ -7,7 +7,8 @@
/// A generic type for representing a CSS [position](https://drafts.csswg.org/css-values/#position). /// A generic type for representing a CSS [position](https://drafts.csswg.org/css-values/#position).
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] #[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage)]
#[derive(PartialEq, ToAnimatedZero, ToComputedValue)]
pub struct Position<H, V> { pub struct Position<H, V> {
/// The horizontal component of position. /// The horizontal component of position.
pub horizontal: H, pub horizontal: H,

View file

@ -102,12 +102,12 @@ impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlP
/// https://www.w3.org/TR/SVG11/painting.html#StrokeProperties /// https://www.w3.org/TR/SVG11/painting.html#StrokeProperties
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToAnimatedValue)] #[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToAnimatedValue)]
#[derive(ToCss, ToComputedValue)] #[derive(ToAnimatedZero, ToCss, ToComputedValue)]
pub enum SvgLengthOrPercentageOrNumber<LengthOrPercentageType, NumberType> { pub enum SvgLengthOrPercentageOrNumber<LengthOrPercentage, Number> {
/// <length> | <percentage> /// <length> | <percentage>
LengthOrPercentage(LengthOrPercentageType), LengthOrPercentage(LengthOrPercentage),
/// <number> /// <number>
Number(NumberType), Number(Number),
} }
impl<L, N> ComputeSquaredDistance for SvgLengthOrPercentageOrNumber<L, N> impl<L, N> ComputeSquaredDistance for SvgLengthOrPercentageOrNumber<L, N>
@ -184,7 +184,8 @@ impl <LengthOrPercentageType: Parse, NumberType: Parse> Parse for
/// An SVG length value supports `context-value` in addition to length. /// An SVG length value supports `context-value` in addition to length.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq)] #[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq)]
#[derive(HasViewportPercentage, ToAnimatedValue, ToComputedValue, ToCss)] #[derive(HasViewportPercentage, ToAnimatedValue, ToAnimatedZero)]
#[derive(ToComputedValue, ToCss)]
pub enum SVGLength<LengthType> { pub enum SVGLength<LengthType> {
/// `<length> | <percentage> | <number>` /// `<length> | <percentage> | <number>`
Length(LengthType), Length(LengthType),
@ -228,7 +229,8 @@ impl<LengthType> ToCss for SVGStrokeDashArray<LengthType> where LengthType: ToCs
/// An SVG opacity value accepts `context-{fill,stroke}-opacity` in /// An SVG opacity value accepts `context-{fill,stroke}-opacity` in
/// addition to opacity value. /// addition to opacity value.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, PartialEq, HasViewportPercentage, ToComputedValue, ToCss)] #[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage)]
#[derive(PartialEq, ToAnimatedZero, ToComputedValue, ToCss)]
pub enum SVGOpacity<OpacityType> { pub enum SVGOpacity<OpacityType> {
/// `<opacity-value>` /// `<opacity-value>`
Opacity(OpacityType), Opacity(OpacityType),

View file

@ -24,7 +24,8 @@ pub struct Matrix<T, U = T> {
/// A generic transform origin. /// A generic transform origin.
#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[cfg_attr(feature = "servo", derive(HeapSizeOf))]
#[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)] #[derive(Clone, ComputeSquaredDistance, Copy, Debug, HasViewportPercentage)]
#[derive(PartialEq, ToAnimatedZero, ToComputedValue, ToCss)]
pub struct TransformOrigin<H, V, Depth> { pub struct TransformOrigin<H, V, Depth> {
/// The horizontal origin. /// The horizontal origin.
pub horizontal: H, pub horizontal: H,

View file

@ -12,6 +12,7 @@ use proc_macro::TokenStream;
mod compute_squared_distance; mod compute_squared_distance;
mod has_viewport_percentage; mod has_viewport_percentage;
mod to_animated_value; mod to_animated_value;
mod to_animated_zero;
mod to_computed_value; mod to_computed_value;
mod to_css; mod to_css;
@ -33,6 +34,12 @@ pub fn derive_to_animated_value(stream: TokenStream) -> TokenStream {
to_animated_value::derive(input).to_string().parse().unwrap() to_animated_value::derive(input).to_string().parse().unwrap()
} }
#[proc_macro_derive(ToAnimatedZero)]
pub fn derive_to_animated_zero(stream: TokenStream) -> TokenStream {
let input = syn::parse_derive_input(&stream.to_string()).unwrap();
to_animated_zero::derive(input).to_string().parse().unwrap()
}
#[proc_macro_derive(ToComputedValue)] #[proc_macro_derive(ToComputedValue)]
pub fn derive_to_computed_value(stream: TokenStream) -> TokenStream { pub fn derive_to_computed_value(stream: TokenStream) -> TokenStream {
let input = syn::parse_derive_input(&stream.to_string()).unwrap(); let input = syn::parse_derive_input(&stream.to_string()).unwrap();

View file

@ -0,0 +1,79 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 quote;
use syn;
use synstructure;
pub fn derive(input: syn::DeriveInput) -> quote::Tokens {
let name = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let mut where_clause = where_clause.clone();
for param in &input.generics.ty_params {
where_clause.predicates.push(
where_predicate(syn::Ty::Path(None, param.ident.clone().into())),
);
}
let to_body = match_body(&input);
quote! {
impl #impl_generics ::values::animated::ToAnimatedZero for #name #ty_generics #where_clause {
#[allow(unused_variables)]
#[inline]
fn to_animated_zero(&self) -> Result<Self, ()> {
match *self {
#to_body
}
}
}
}
}
fn match_body(input: &syn::DeriveInput) -> quote::Tokens {
synstructure::each_variant(&input, &synstructure::BindStyle::Ref.into(), |fields, variant| {
let name = if let syn::Body::Enum(_) = input.body {
format!("{}::{}", input.ident, variant.ident).into()
} else {
variant.ident.clone()
};
let (zero, computed_fields) = synstructure::match_pattern(
&name,
&variant.data,
&synstructure::BindStyle::Move.into(),
);
let fields_pairs = fields.iter().zip(computed_fields.iter());
let mut computations = quote!();
computations.append_all(fields_pairs.map(|(field, computed_field)| {
quote! {
let #computed_field = ::values::animated::ToAnimatedZero::to_animated_zero(#field)?;
}
}));
Some(quote!(
#computations
Ok(#zero)
))
})
}
fn where_predicate(ty: syn::Ty) -> syn::WherePredicate {
syn::WherePredicate::BoundPredicate(syn::WhereBoundPredicate {
bound_lifetimes: vec![],
bounded_ty: ty,
bounds: vec![syn::TyParamBound::Trait(
syn::PolyTraitRef {
bound_lifetimes: vec![],
trait_ref: syn::Path {
global: true,
segments: vec![
"values".into(),
"animated".into(),
"ToAnimatedZero".into(),
],
},
},
syn::TraitBoundModifier::None,
)],
})
}