diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2017-06-04 10:02:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-04 10:02:28 -0700 |
commit | 942fce3a0bcc307caabecec42bc65265fbee6688 (patch) | |
tree | 66c3577b2f8e9b80639894a3c01354e9a7abc6f5 | |
parent | 7176e3ae9e399c413eed0559c68c0ba1945040bb (diff) | |
parent | c4f1d647a01f794f7b08b5b861f44bf274e6c03e (diff) | |
download | servo-942fce3a0bcc307caabecec42bc65265fbee6688.tar.gz servo-942fce3a0bcc307caabecec42bc65265fbee6688.zip |
Auto merge of #17152 - servo:derive-all-the-things, r=emilio
Derive the most trivial ToCss implementations π
<!-- Reviewable:start -->
This change isβ[<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17152)
<!-- Reviewable:end -->
18 files changed, 113 insertions, 263 deletions
diff --git a/components/style/properties/helpers.mako.rs b/components/style/properties/helpers.mako.rs index f815dc6cc49..c7031be3ebb 100644 --- a/components/style/properties/helpers.mako.rs +++ b/components/style/properties/helpers.mako.rs @@ -1074,8 +1074,6 @@ predefined_type=length_type, logical=logical, **kwargs)"> - use std::fmt; - use style_traits::ToCss; % if not logical: use values::specified::AllowQuirks; % endif @@ -1085,8 +1083,8 @@ pub type T = ::values::computed::${length_type}; } - #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)] pub struct SpecifiedValue(pub ${length_type}); % if length_type == "MozLength": @@ -1131,12 +1129,6 @@ ret.map(SpecifiedValue) } - impl ToCss for SpecifiedValue { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } - } - impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; #[inline] diff --git a/components/style/properties/longhand/border.mako.rs b/components/style/properties/longhand/border.mako.rs index f2eae0dfe42..693d1f32551 100644 --- a/components/style/properties/longhand/border.mako.rs +++ b/components/style/properties/longhand/border.mako.rs @@ -222,8 +222,8 @@ ${helpers.predefined_type("border-image-outset", "LengthOrNumberRect", pub mod computed_value { pub use super::RepeatKeyword; - #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[derive(Debug, Clone, PartialEq, ToCss)] pub struct T(pub RepeatKeyword, pub RepeatKeyword); } @@ -238,14 +238,6 @@ ${helpers.predefined_type("border-image-outset", "LengthOrNumberRect", "round" => Round, "space" => Space); - - impl ToCss for computed_value::T { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - try!(self.0.to_css(dest)); - try!(dest.write_str(" ")); - self.1.to_css(dest) - } - } impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { try!(self.0.to_css(dest)); diff --git a/components/style/properties/longhand/color.mako.rs b/components/style/properties/longhand/color.mako.rs index 238b8689e26..0728516ab41 100644 --- a/components/style/properties/longhand/color.mako.rs +++ b/components/style/properties/longhand/color.mako.rs @@ -13,8 +13,6 @@ ignored_when_colors_disabled="True" spec="https://drafts.csswg.org/css-color/#color"> use cssparser::RGBA; - use std::fmt; - use style_traits::ToCss; use values::specified::{AllowQuirks, Color, CSSColor}; impl ToComputedValue for SpecifiedValue { @@ -31,17 +29,11 @@ } } - #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[derive(Clone, Debug, PartialEq, ToCss)] pub struct SpecifiedValue(pub CSSColor); no_viewport_percentage!(SpecifiedValue); - impl ToCss for SpecifiedValue { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } - } - pub mod computed_value { use cssparser; pub type T = cssparser::RGBA; @@ -91,6 +83,9 @@ %> use gecko_bindings::bindings::Gecko_GetLookAndFeelSystemColor; use gecko_bindings::structs::root::mozilla::LookAndFeel_ColorID; + use std::fmt; + use style_traits::ToCss; + pub type SystemColor = LookAndFeel_ColorID; impl ToCss for SystemColor { diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index 37410b1be82..2c491a1630a 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -2149,18 +2149,15 @@ ${helpers.single_keyword("-moz-math-variant", internal="True" disable_when_testing="True"> use app_units::Au; use gecko_bindings::structs::NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT; - use std::fmt; - use style_traits::ToCss; use values::specified::length::{AU_PER_PT, FontBaseSize, NoCalcLength}; - #[derive(Clone, Debug, HasViewportPercentage, PartialEq)] + #[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)] pub struct SpecifiedValue(pub NoCalcLength); pub mod computed_value { pub type T = super::Au; } - impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; @@ -2185,12 +2182,6 @@ ${helpers.single_keyword("-moz-math-variant", } } - impl ToCss for SpecifiedValue { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } - } - #[inline] pub fn get_initial_value() -> computed_value::T { Au((NS_MATHML_DEFAULT_SCRIPT_MIN_SIZE_PT as f32 * AU_PER_PT) as i32) diff --git a/components/style/properties/longhand/inherited_table.mako.rs b/components/style/properties/longhand/inherited_table.mako.rs index 424d74a5b4c..1cf2c14fbe0 100644 --- a/components/style/properties/longhand/inherited_table.mako.rs +++ b/components/style/properties/longhand/inherited_table.mako.rs @@ -31,8 +31,8 @@ ${helpers.single_keyword("caption-side", "top bottom", use app_units::Au; use properties::animated_properties::Animatable; - #[derive(Clone, Copy, Debug, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[derive(Clone, Copy, Debug, PartialEq, ToCss)] pub struct T { pub horizontal: Au, pub vertical: Au, @@ -92,14 +92,6 @@ ${helpers.single_keyword("caption-side", "top bottom", } } - impl ToCss for computed_value::T { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - try!(self.horizontal.to_css(dest)); - try!(dest.write_str(" ")); - self.vertical.to_css(dest) - } - } - impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 8b1dafb5cd4..690d50d7908 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -443,8 +443,8 @@ ${helpers.predefined_type("word-spacing", #[cfg_attr(feature = "servo", derive(HeapSizeOf))] pub struct T(pub SmallVec<[TextShadow; 1]>); - #[derive(Clone, PartialEq, Debug)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[derive(Clone, PartialEq, Debug, ToCss)] pub struct TextShadow { pub offset_x: Au, pub offset_y: Au, @@ -468,18 +468,6 @@ ${helpers.predefined_type("word-spacing", } } - impl ToCss for computed_value::TextShadow { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.offset_x.to_css(dest)?; - dest.write_str(" ")?; - self.offset_y.to_css(dest)?; - dest.write_str(" ")?; - self.blur_radius.to_css(dest)?; - dest.write_str(" ")?; - self.color.to_css(dest) - } - } - impl ToCss for SpecifiedValue { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { let mut iter = self.0.iter(); @@ -767,7 +755,6 @@ ${helpers.predefined_type("word-spacing", <%helpers:longhand name="text-emphasis-position" animation_value_type="none" products="gecko" spec="https://drafts.csswg.org/css-text-decor/#propdef-text-emphasis-position"> - use std::fmt; use values::computed::ComputedValueAsSpecified; use style_traits::ToCss; @@ -778,8 +765,8 @@ ${helpers.predefined_type("word-spacing", "right" => Right, "left" => Left); - #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[derive(Debug, Clone, PartialEq, ToCss)] pub struct SpecifiedValue(pub HorizontalWritingModeValue, pub VerticalWritingModeValue); pub mod computed_value { @@ -804,15 +791,6 @@ ${helpers.predefined_type("word-spacing", } } - impl ToCss for SpecifiedValue { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - let SpecifiedValue(horizontal, vertical) = *self; - try!(horizontal.to_css(dest)); - try!(dest.write_char(' ')); - vertical.to_css(dest) - } - } - % if product == "gecko": impl SpecifiedValue { pub fn from_gecko_keyword(kw: u32) -> Self { diff --git a/components/style/properties/longhand/list.mako.rs b/components/style/properties/longhand/list.mako.rs index 01b19d7d4fd..34f51b97b9d 100644 --- a/components/style/properties/longhand/list.mako.rs +++ b/components/style/properties/longhand/list.mako.rs @@ -114,17 +114,15 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu <%helpers:longhand name="list-style-image" animation_value_type="none" boxed="${product == 'gecko'}" spec="https://drafts.csswg.org/css-lists/#propdef-list-style-image"> - use std::fmt; use values::computed::ComputedValueAsSpecified; use values::specified::UrlOrNone; pub use self::computed_value::T as SpecifiedValue; - use style_traits::ToCss; pub mod computed_value { use values::specified::UrlOrNone; - #[derive(Debug, Clone, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] + #[derive(Debug, Clone, PartialEq, ToCss)] pub struct T(pub UrlOrNone); } @@ -132,12 +130,6 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu impl ComputedValueAsSpecified for SpecifiedValue {} no_viewport_percentage!(SpecifiedValue); - impl ToCss for SpecifiedValue { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } - } - #[inline] pub fn get_initial_value() -> computed_value::T { computed_value::T(Either::Second(None_)) diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index e5b35428bef..3d59a51ff42 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -623,9 +623,9 @@ pub type LengthOrNormal = Either<Length, Normal>; /// A value suitable for a `min-width`, `min-height`, `width` or `height` property. /// See specified/values/length.rs for more details. -#[derive(Debug, Copy, Clone, PartialEq)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Copy, Debug, PartialEq, ToCss)] pub enum MozLength { LengthOrPercentageOrAuto(LengthOrPercentageOrAuto), ExtremumLength(ExtremumLength), @@ -665,22 +665,11 @@ impl ToComputedValue for specified::MozLength { } } -impl ToCss for MozLength { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - MozLength::LengthOrPercentageOrAuto(lopoa) => - lopoa.to_css(dest), - MozLength::ExtremumLength(ext) => - ext.to_css(dest), - } - } -} - /// A value suitable for a `max-width` or `max-height` property. /// See specified/values/length.rs for more details. -#[derive(Debug, Copy, Clone, PartialEq)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Copy, Debug, PartialEq, ToCss)] pub enum MaxLength { LengthOrPercentageOrNone(LengthOrPercentageOrNone), ExtremumLength(ExtremumLength), @@ -718,14 +707,3 @@ impl ToComputedValue for specified::MaxLength { } } } - -impl ToCss for MaxLength { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - MaxLength::LengthOrPercentageOrNone(lopon) => - lopon.to_css(dest), - MaxLength::ExtremumLength(ext) => - ext.to_css(dest), - } - } -} diff --git a/components/style/values/computed/mod.rs b/components/style/values/computed/mod.rs index 039c3763567..1fbce99389e 100644 --- a/components/style/values/computed/mod.rs +++ b/components/style/values/computed/mod.rs @@ -481,9 +481,9 @@ pub struct Shadow { /// A `<number>` value. pub type Number = CSSFloat; -#[derive(Debug, Copy, Clone, PartialEq)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Copy, Debug, PartialEq, ToCss)] pub enum NumberOrPercentage { Percentage(Percentage), Number(Number), @@ -512,15 +512,6 @@ impl ToComputedValue for specified::NumberOrPercentage { } } -impl ToCss for NumberOrPercentage { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - NumberOrPercentage::Percentage(percentage) => percentage.to_css(dest), - NumberOrPercentage::Number(number) => number.to_css(dest), - } - } -} - /// A type used for opacity. pub type Opacity = CSSFloat; diff --git a/components/style/values/generics/basic_shape.rs b/components/style/values/generics/basic_shape.rs index a507d15a4ec..b2d402dd38f 100644 --- a/components/style/values/generics/basic_shape.rs +++ b/components/style/values/generics/basic_shape.rs @@ -53,7 +53,7 @@ pub enum ShapeSource<BasicShape, ReferenceBox> { #[allow(missing_docs)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Debug, PartialEq, ToComputedValue)] +#[derive(Clone, Debug, PartialEq, ToComputedValue, ToCss)] pub enum BasicShape<H, V, LengthOrPercentage> { Inset(InsetRect<LengthOrPercentage>), Circle(Circle<H, V, LengthOrPercentage>), @@ -153,23 +153,6 @@ impl ToCss for GeometryBox { } } -impl<H, V, L> ToCss for BasicShape<H, V, L> - where H: ToCss, - V: ToCss, - L: PartialEq + ToCss, - Circle<H, V, L>: ToCss, - Ellipse<H, V, L>: ToCss, -{ - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - BasicShape::Inset(ref rect) => rect.to_css(dest), - BasicShape::Circle(ref circle) => circle.to_css(dest), - BasicShape::Ellipse(ref ellipse) => ellipse.to_css(dest), - BasicShape::Polygon(ref polygon) => polygon.to_css(dest), - } - } -} - impl<L> ToCss for InsetRect<L> where L: ToCss + PartialEq { diff --git a/components/style/values/generics/image.rs b/components/style/values/generics/image.rs index 9aa49428dce..5965db357dc 100644 --- a/components/style/values/generics/image.rs +++ b/components/style/values/generics/image.rs @@ -108,8 +108,8 @@ impl ComputedValueAsSpecified for ShapeExtent {} /// A gradient item. /// https://drafts.csswg.org/css-images-4/#color-stop-syntax -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)] pub enum GradientItem<Color, LengthOrPercentage> { /// A color stop. ColorStop(ColorStop<Color, LengthOrPercentage>), @@ -288,17 +288,6 @@ impl<L, LoP> ToCss for EndingShape<L, LoP> } } -impl<C, L> ToCss for GradientItem<C, L> - where C: ToCss, L: ToCss, -{ - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - GradientItem::ColorStop(ref stop) => stop.to_css(dest), - GradientItem::InterpolationHint(ref hint) => hint.to_css(dest), - } - } -} - impl<C, L> fmt::Debug for ColorStop<C, L> where C: fmt::Debug, L: fmt::Debug, { diff --git a/components/style/values/generics/transform.rs b/components/style/values/generics/transform.rs index 7cbc9ce4521..9fe5a8cab93 100644 --- a/components/style/values/generics/transform.rs +++ b/components/style/values/generics/transform.rs @@ -4,12 +4,9 @@ //! Generic types for CSS values that are related to transformations. -use std::fmt; -use style_traits::ToCss; - /// A generic transform origin. #[cfg_attr(feature = "servo", derive(HeapSizeOf))] -#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue)] +#[derive(Clone, Copy, Debug, HasViewportPercentage, PartialEq, ToComputedValue, ToCss)] pub struct TransformOrigin<H, V, Depth> { /// The horizontal origin. pub horizontal: H, @@ -29,17 +26,3 @@ impl<H, V, D> TransformOrigin<H, V, D> { } } } - -impl<H, V, D> ToCss for TransformOrigin<H, V, D> - where H: ToCss, V: ToCss, D: ToCss, -{ - fn to_css<W>(&self, dest: &mut W) -> fmt::Result - where W: fmt::Write, - { - self.horizontal.to_css(dest)?; - dest.write_str(" ")?; - self.vertical.to_css(dest)?; - dest.write_str(" ")?; - self.depth.to_css(dest) - } -} diff --git a/components/style/values/mod.rs b/components/style/values/mod.rs index bbb6603bb90..506584c1e76 100644 --- a/components/style/values/mod.rs +++ b/components/style/values/mod.rs @@ -34,9 +34,9 @@ define_keyword_type!(None_, "none"); define_keyword_type!(Auto, "auto"); define_keyword_type!(Normal, "normal"); -#[derive(Clone, Copy, HasViewportPercentage, PartialEq)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] /// A struct representing one of two kinds of values. +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Copy, HasViewportPercentage, PartialEq, ToCss)] pub enum Either<A, B> { /// The first value. First(A), @@ -53,15 +53,6 @@ impl<A: Debug, B: Debug> Debug for Either<A, B> { } } -impl<A: ToCss, B: ToCss> ToCss for Either<A, B> { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - Either::First(ref v) => v.to_css(dest), - Either::Second(ref v) => v.to_css(dest), - } - } -} - impl<A: Parse, B: Parse> Parse for Either<A, B> { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Either<A, B>, ()> { if let Ok(v) = input.try(|i| A::parse(context, i)) { diff --git a/components/style/values/specified/align.rs b/components/style/values/specified/align.rs index c0e34a2f2a2..6fb637b6942 100644 --- a/components/style/values/specified/align.rs +++ b/components/style/values/specified/align.rs @@ -209,7 +209,7 @@ impl Parse for AlignJustifyContent { /// Value of the `align-self` or `justify-self` property. /// /// https://drafts.csswg.org/css-align/#self-alignment -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, ToCss)] pub struct AlignJustifySelf(pub AlignFlags); impl AlignJustifySelf { @@ -228,12 +228,6 @@ impl AlignJustifySelf { no_viewport_percentage!(AlignJustifySelf); -impl ToCss for AlignJustifySelf { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } -} - impl Parse for AlignJustifySelf { // auto | normal | stretch | <baseline-position> | // [ <overflow-position>? && <self-position> ] @@ -253,7 +247,7 @@ impl Parse for AlignJustifySelf { /// Value of the `align-items` property /// /// https://drafts.csswg.org/css-align/#self-alignment -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, ToCss)] pub struct AlignItems(pub AlignFlags); impl AlignItems { @@ -272,12 +266,6 @@ impl AlignItems { no_viewport_percentage!(AlignItems); -impl ToCss for AlignItems { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } -} - impl Parse for AlignItems { // normal | stretch | <baseline-position> | // [ <overflow-position>? && <self-position> ] @@ -297,7 +285,7 @@ impl Parse for AlignItems { /// Value of the `justify-items` property /// /// https://drafts.csswg.org/css-align/#justify-items-property -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, ToCss)] pub struct JustifyItems(pub AlignFlags); impl JustifyItems { @@ -316,12 +304,6 @@ impl JustifyItems { no_viewport_percentage!(JustifyItems); -impl ToCss for JustifyItems { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } -} - impl Parse for JustifyItems { // auto | normal | stretch | <baseline-position> | // [ <overflow-position>? && <self-position> ] diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 6273fec31fd..61335ee0e55 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -531,8 +531,8 @@ impl NoCalcLength { /// This is commonly used for the `<length>` values. /// /// https://drafts.csswg.org/css-values/#lengths -#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)] pub enum Length { /// The internal length type that cannot parse `calc` NoCalc(NoCalcLength), @@ -549,15 +549,6 @@ impl From<NoCalcLength> for Length { } } -impl ToCss for Length { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - Length::NoCalc(ref inner) => inner.to_css(dest), - Length::Calc(ref calc) => calc.to_css(dest), - } - } -} - impl Mul<CSSFloat> for Length { type Output = Length; @@ -758,9 +749,9 @@ impl Parse for Percentage { impl ComputedValueAsSpecified for Percentage {} /// A length or a percentage value. -#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)] pub enum LengthOrPercentage { Length(NoCalcLength), Percentage(Percentage), @@ -790,16 +781,6 @@ impl From<Percentage> for LengthOrPercentage { } } -impl ToCss for LengthOrPercentage { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - LengthOrPercentage::Length(ref length) => length.to_css(dest), - LengthOrPercentage::Percentage(percentage) => percentage.to_css(dest), - LengthOrPercentage::Calc(ref calc) => calc.to_css(dest), - } - } -} - impl LengthOrPercentage { #[inline] /// Returns a `zero` length. @@ -1213,25 +1194,14 @@ impl LengthOrNumber { /// A value suitable for a `min-width` or `min-height` property. /// Unlike `max-width` or `max-height` properties, a MozLength can be /// `auto`, and cannot be `none`. -#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)] pub enum MozLength { LengthOrPercentageOrAuto(LengthOrPercentageOrAuto), ExtremumLength(ExtremumLength), } -impl ToCss for MozLength { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - MozLength::LengthOrPercentageOrAuto(ref lopoa) => - lopoa.to_css(dest), - MozLength::ExtremumLength(ref ext) => - ext.to_css(dest), - } - } -} - impl Parse for MozLength { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { MozLength::parse_quirky(context, input, AllowQuirks::No) @@ -1250,25 +1220,14 @@ impl MozLength { } /// A value suitable for a `max-width` or `max-height` property. -#[derive(Clone, Debug, HasViewportPercentage, PartialEq)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Debug, HasViewportPercentage, PartialEq, ToCss)] pub enum MaxLength { LengthOrPercentageOrNone(LengthOrPercentageOrNone), ExtremumLength(ExtremumLength), } -impl ToCss for MaxLength { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - MaxLength::LengthOrPercentageOrNone(ref lopon) => - lopon.to_css(dest), - MaxLength::ExtremumLength(ref ext) => - ext.to_css(dest), - } - } -} - impl Parse for MaxLength { fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> { MaxLength::parse_quirky(context, input, AllowQuirks::No) diff --git a/components/style/values/specified/mod.rs b/components/style/values/specified/mod.rs index 7bd45a3e753..2b9f3eddefa 100644 --- a/components/style/values/specified/mod.rs +++ b/components/style/values/specified/mod.rs @@ -652,9 +652,9 @@ impl ToCss for Number { /// <number-percentage> /// Accepts only non-negative numbers. -#[derive(Clone, Copy, Debug, PartialEq)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Copy, Debug, PartialEq, ToCss)] pub enum NumberOrPercentage { Percentage(Percentage), Number(Number), @@ -686,18 +686,9 @@ impl Parse for NumberOrPercentage { } } -impl ToCss for NumberOrPercentage { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - match *self { - NumberOrPercentage::Percentage(percentage) => percentage.to_css(dest), - NumberOrPercentage::Number(number) => number.to_css(dest), - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] -#[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] +#[cfg_attr(feature = "servo", derive(HeapSizeOf))] +#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, ToCss)] pub struct Opacity(Number); no_viewport_percentage!(Opacity); @@ -722,12 +713,6 @@ impl ToComputedValue for Opacity { } } -impl ToCss for Opacity { - fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { - self.0.to_css(dest) - } -} - #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] #[cfg_attr(feature = "servo", derive(HeapSizeOf))] #[allow(missing_docs)] diff --git a/components/style_derive/lib.rs b/components/style_derive/lib.rs index 7f4743dccd7..0f39a7deca1 100644 --- a/components/style_derive/lib.rs +++ b/components/style_derive/lib.rs @@ -11,6 +11,7 @@ use proc_macro::TokenStream; mod has_viewport_percentage; mod to_computed_value; +mod to_css; #[proc_macro_derive(HasViewportPercentage)] pub fn derive_has_viewport_percentage(stream: TokenStream) -> TokenStream { @@ -23,3 +24,9 @@ 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() } + +#[proc_macro_derive(ToCss)] +pub fn derive_to_css(stream: TokenStream) -> TokenStream { + let input = syn::parse_derive_input(&stream.to_string()).unwrap(); + to_css::derive(input).to_string().parse().unwrap() +} diff --git a/components/style_derive/to_css.rs b/components/style_derive/to_css.rs new file mode 100644 index 00000000000..774add083fa --- /dev/null +++ b/components/style_derive/to_css.rs @@ -0,0 +1,70 @@ +/* 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 style = synstructure::BindStyle::Ref.into(); + let match_body = synstructure::each_variant(&input, &style, |bindings, _| { + if bindings.is_empty() { + panic!("unit variants are not yet supported"); + } + let (first, rest) = bindings.split_first().expect("unit variants are not yet supported"); + where_clause.predicates.push(where_predicate(first.field.ty.clone())); + let mut expr = quote! { + ::style_traits::ToCss::to_css(#first, dest) + }; + for binding in rest { + where_clause.predicates.push(where_predicate(binding.field.ty.clone())); + expr = quote! { + #expr?; + dest.write_str(" ")?; + ::style_traits::ToCss::to_css(#binding, dest) + }; + } + Some(expr) + }); + + quote! { + impl #impl_generics ::style_traits::ToCss for #name #ty_generics #where_clause { + #[allow(unused_variables, unused_imports)] + #[inline] + fn to_css<W>(&self, dest: &mut W) -> ::std::fmt::Result + where + W: ::std::fmt::Write + { + match *self { + #match_body + } + } + } + } +} + +/// `#ty: ::style_traits::ToCss` +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!["style_traits".into(), "ToCss".into()], + }, + }, + syn::TraitBoundModifier::None + )], + }) +} |