Change ToCss to take a CssWriter<W>

This more concrete wrapper type can write a prefix the very first time something
is written to it. This allows removing plenty of useless monomorphisations caused
by the former W/SequenceWriter<W> pair of types.
This commit is contained in:
Anthony Ramine 2018-01-22 19:58:01 +01:00
parent 3672856efa
commit cd8f96cc9e
89 changed files with 873 additions and 533 deletions

View file

@ -5,8 +5,8 @@
//! CSS handling for the [`basic-shape`](https://drafts.csswg.org/css-shapes/#typedef-basic-shape)
//! types that are generic over their `ToCss` implementations.
use std::fmt;
use style_traits::ToCss;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
use values::animated::{Animate, Procedure, ToAnimatedZero};
use values::distance::{ComputeSquaredDistance, SquaredDistance};
use values::generics::border::BorderRadius;
@ -152,7 +152,10 @@ impl<B, T, U> ToAnimatedZero for ShapeSource<B, T, U> {
impl<L> ToCss for InsetRect<L>
where L: ToCss + PartialEq
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
dest.write_str("inset(")?;
self.rect.to_css(dest)?;
if let Some(ref radius) = self.round {
@ -210,7 +213,10 @@ where
}
impl<L: ToCss> ToCss for Polygon<L> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
dest.write_str("polygon(")?;
if self.fill != FillRule::default() {
self.fill.to_css(dest)?;

View file

@ -4,8 +4,8 @@
//! Generic types for CSS values related to borders.
use std::fmt;
use style_traits::ToCss;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
use values::generics::rect::Rect;
use values::generics::size::Size;
@ -84,8 +84,9 @@ impl<N> From<N> for BorderImageSlice<N>
impl<N> ToCss for BorderImageSlice<N>
where N: PartialEq + ToCss,
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::Write
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
self.offsets.to_css(dest)?;
if self.fill {
@ -118,8 +119,13 @@ impl<L> BorderRadius<L>
{
/// Serialises two given rects following the syntax of the `border-radius``
/// property.
pub fn serialize_rects<W>(widths: Rect<&L>, heights: Rect<&L>, dest: &mut W) -> fmt::Result
where W: fmt::Write,
pub fn serialize_rects<W>(
widths: Rect<&L>,
heights: Rect<&L>,
dest: &mut CssWriter<W>,
) -> fmt::Result
where
W: Write,
{
widths.to_css(dest)?;
if widths.0 != heights.0 || widths.1 != heights.1 || widths.2 != heights.2 || widths.3 != heights.3 {
@ -133,7 +139,10 @@ impl<L> BorderRadius<L>
impl<L> ToCss for BorderRadius<L>
where L: PartialEq + ToCss
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
let BorderRadius {
top_left: BorderCornerRadius(ref tl),
top_right: BorderCornerRadius(ref tr),

View file

@ -5,7 +5,7 @@
//! Generic types for counters-related CSS values.
use std::fmt;
use style_traits::ToCss;
use style_traits::{CssWriter, ToCss};
use values::CustomIdent;
/// A generic value for the `counter-increment` property.
@ -27,7 +27,7 @@ where
I: ToCss,
{
#[inline]
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
{

View file

@ -4,8 +4,8 @@
//! Generic types for CSS values related to effects.
use std::fmt;
use style_traits::values::{SequenceWriter, ToCss};
use std::fmt::{self, Write};
use style_traits::values::{CssWriter, SequenceWriter, ToCss};
#[cfg(feature = "gecko")]
use values::specified::url::SpecifiedUrl;
@ -88,9 +88,9 @@ where
BlurShapeLength: ToCss,
ShapeLength: ToCss,
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
W: Write,
{
{
let mut writer = SequenceWriter::new(&mut *dest, " ");

View file

@ -7,8 +7,9 @@
use cssparser::Parser;
use parser::{Parse, ParserContext};
use std::{fmt, mem, usize};
use style_traits::{ToCss, ParseError, StyleParseErrorKind};
use std::{mem, usize};
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
use values::{CSSFloat, CustomIdent};
use values::computed::{Context, ToComputedValue};
use values::specified;
@ -49,7 +50,10 @@ impl<Integer> ToCss for GridLine<Integer>
where
Integer: ToCss,
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
if self.is_auto() {
return dest.write_str("auto")
}
@ -230,7 +234,10 @@ impl<L: PartialEq> TrackSize<L> {
}
impl<L: ToCss> ToCss for TrackSize<L> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
match *self {
TrackSize::Breadth(ref breadth) => breadth.to_css(dest),
TrackSize::Minmax(ref min, ref max) => {
@ -315,10 +322,10 @@ pub fn concat_serialize_idents<W>(
suffix: &str,
slice: &[CustomIdent],
sep: &str,
dest: &mut W,
dest: &mut CssWriter<W>,
) -> fmt::Result
where
W: fmt::Write
W: Write,
{
if let Some((ref first, rest)) = slice.split_first() {
dest.write_str(prefix)?;
@ -385,7 +392,10 @@ pub struct TrackRepeat<L, I> {
}
impl<L: ToCss, I: ToCss> ToCss for TrackRepeat<L, I> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
dest.write_str("repeat(")?;
self.count.to_css(dest)?;
dest.write_str(", ")?;
@ -503,7 +513,10 @@ pub struct TrackList<LengthOrPercentage, Integer> {
}
impl<L: ToCss, I: ToCss> ToCss for TrackList<L, I> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
let auto_idx = match self.list_type {
TrackListType::Auto(i) => i as usize,
_ => usize::MAX,
@ -614,7 +627,10 @@ impl Parse for LineNameList {
}
impl ToCss for LineNameList {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
dest.write_str("subgrid")?;
let fill_idx = self.fill_idx.map(|v| v as usize).unwrap_or(usize::MAX);
for (i, names) in self.names.iter().enumerate() {

View file

@ -10,8 +10,8 @@ use Atom;
use cssparser::serialize_identifier;
use custom_properties;
use servo_arc::Arc;
use std::fmt;
use style_traits::ToCss;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
/// An [image].
///
@ -143,7 +143,10 @@ pub struct PaintWorklet {
trivial_to_computed_value!(PaintWorklet);
impl ToCss for PaintWorklet {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
dest.write_str("paint(")?;
serialize_identifier(&*self.name.to_string(), dest)?;
for argument in &self.arguments {
@ -169,17 +172,23 @@ pub struct MozImageRect<NumberOrPercentage, MozImageRectUrl> {
}
impl<G, R, U> fmt::Debug for Image<G, R, U>
where G: fmt::Debug, R: fmt::Debug, U: fmt::Debug + ToCss
where
G: ToCss,
R: ToCss,
U: ToCss,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.to_css(f)
self.to_css(&mut CssWriter::new(f))
}
}
impl<G, R, U> ToCss for Image<G, R, U>
where G: ToCss, R: ToCss, U: ToCss
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
match *self {
Image::Url(ref url) => url.to_css(dest),
Image::Gradient(ref gradient) => gradient.to_css(dest),
@ -198,7 +207,10 @@ impl<G, R, U> ToCss for Image<G, R, U>
impl<D, L, LoP, P, C, A> ToCss for Gradient<D, L, LoP, P, C, A>
where D: LineDirection, L: ToCss, LoP: ToCss, P: ToCss, C: ToCss, A: ToCss
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
match self.compat_mode {
CompatMode::WebKit => dest.write_str("-webkit-")?,
CompatMode::Moz => dest.write_str("-moz-")?,
@ -272,17 +284,17 @@ pub trait LineDirection {
fn points_downwards(&self, compat_mode: CompatMode) -> bool;
/// Serialises this direction according to the compatibility mode.
fn to_css<W>(&self, dest: &mut W, compat_mode: CompatMode) -> fmt::Result
where W: fmt::Write;
fn to_css<W>(&self, dest: &mut CssWriter<W>, compat_mode: CompatMode) -> fmt::Result
where W: Write;
}
impl<L> ToCss for Circle<L>
where
L: ToCss,
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
W: Write,
{
match *self {
Circle::Extent(ShapeExtent::FarthestCorner) |

View file

@ -8,8 +8,9 @@
use counter_style::{Symbols, parse_counter_style_name};
use cssparser::Parser;
use parser::{Parse, ParserContext};
use std::fmt;
use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss};
use std::fmt::{self, Write};
use style_traits::{Comma, CssWriter, OneOrMoreSeparated, ParseError};
use style_traits::{StyleParseErrorKind, ToCss};
use super::CustomIdent;
pub mod background;
@ -144,7 +145,10 @@ impl<T> OneOrMoreSeparated for FontSettingTag<T> {
}
impl<T: ToCss> ToCss for FontSettingTag<T> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
use byteorder::{BigEndian, ByteOrder};
use std::str;
@ -231,7 +235,10 @@ pub struct FontSettingTagInt(pub u32);
pub struct FontSettingTagFloat(pub f32);
impl ToCss for FontSettingTagInt {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
match self.0 {
1 => Ok(()),
0 => dest.write_str(" off"),
@ -273,7 +280,10 @@ impl Parse for FontSettingTagFloat {
}
impl ToCss for FontSettingTagFloat {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
dest.write_str(" ")?;
self.0.to_css(dest)
}

View file

@ -6,8 +6,8 @@
use cssparser::Parser;
use parser::{Parse, ParserContext};
use std::fmt;
use style_traits::{ToCss, ParseError};
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, ToCss};
/// A CSS value made of four components, where its `ToCss` impl will try to
/// serialize as few components as possible, like for example in `border-width`.
@ -68,8 +68,9 @@ impl<T> Parse for Rect<T>
impl<T> ToCss for Rect<T>
where T: PartialEq + ToCss
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where W: fmt::Write,
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
self.0.to_css(dest)?;
let same_vertical = self.0 == self.2;

View file

@ -7,8 +7,8 @@
use cssparser::Parser;
use euclid::Size2D;
use parser::ParserContext;
use std::fmt;
use style_traits::{ToCss, ParseError};
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, ToCss};
use values::animated::ToAnimatedValue;
/// A generic size, for `border-*-radius` longhand properties, or
@ -56,9 +56,9 @@ impl<L> ToCss for Size<L>
where L:
ToCss + PartialEq,
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where W:
fmt::Write
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
self.0.width.to_css(dest)?;

View file

@ -6,8 +6,8 @@
use cssparser::Parser;
use parser::{Parse, ParserContext};
use std::fmt;
use style_traits::{ParseError, StyleParseErrorKind, ToCss};
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
use values::{Either, None_};
use values::computed::NumberOrPercentage;
use values::computed::length::LengthOrPercentage;
@ -209,7 +209,10 @@ pub enum SVGStrokeDashArray<LengthType> {
}
impl<LengthType> ToCss for SVGStrokeDashArray<LengthType> where LengthType: ToCss {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
match self {
&SVGStrokeDashArray::Values(ref values) => {
let mut iter = values.iter();

View file

@ -7,8 +7,8 @@
use app_units::Au;
use euclid::{self, Rect, Transform3D};
use num_traits::Zero;
use std::fmt;
use style_traits::ToCss;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ToCss};
use values::{computed, CSSFloat};
use values::computed::length::Length as ComputedLength;
use values::computed::length::LengthOrPercentage as ComputedLengthOrPercentage;
@ -136,9 +136,9 @@ where
Integer: ToCss,
Number: ToCss,
{
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
W: Write,
{
match *self {
TimingFunction::Keyword(keyword) => keyword.to_css(dest),
@ -546,7 +546,10 @@ impl<Angle: ToCss + Copy, Number: ToCss + Copy, Length: ToCss,
Integer: ToCss + Copy, LengthOrNumber: ToCss, LengthOrPercentage: ToCss, LoPoNumber: ToCss>
ToCss for
TransformOperation<Angle, Number, Length, Integer, LengthOrNumber, LengthOrPercentage, LoPoNumber> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
match *self {
TransformOperation::Matrix(ref m) => m.to_css(dest),
TransformOperation::PrefixedMatrix(ref m) => m.to_css(dest),
@ -653,9 +656,9 @@ impl<Angle: ToCss + Copy, Number: ToCss + Copy, Length: ToCss,
}
impl<T: ToCss> ToCss for Transform<T> {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: fmt::Write,
W: Write,
{
if self.0.is_empty() {
return dest.write_str("none");