style: Cleanup a bit the counter style code.

Use more compact types, and remove some manual implementations that can be
derived.

Differential Revision: https://phabricator.services.mozilla.com/D31315
This commit is contained in:
Emilio Cobos Álvarez 2019-05-16 23:05:00 +00:00
parent 3034d66eef
commit 7d3997d7ef
2 changed files with 57 additions and 81 deletions

View file

@ -19,7 +19,6 @@ use selectors::parser::SelectorParseErrorKind;
use std::fmt::{self, Write};
use std::mem;
use std::num::Wrapping;
use std::ops::Range;
use style_traits::{Comma, CssWriter, OneOrMoreSeparated, ParseError};
use style_traits::{StyleParseErrorKind, ToCss};
@ -261,7 +260,7 @@ counter_style_descriptors! {
"suffix" suffix / set_suffix [_]: Symbol,
/// <https://drafts.csswg.org/css-counter-styles/#counter-style-range>
"range" range / set_range [_]: Ranges,
"range" range / set_range [_]: CounterRanges,
/// <https://drafts.csswg.org/css-counter-styles/#counter-style-pad>
"pad" pad / set_pad [_]: Pad,
@ -371,7 +370,7 @@ impl Parse for System {
"additive" => Ok(System::Additive),
"fixed" => {
let first_symbol_value = input.try(|i| Integer::parse(context, i)).ok();
Ok(System::Fixed { first_symbol_value: first_symbol_value })
Ok(System::Fixed { first_symbol_value })
}
"extends" => {
let other = parse_counter_style_name(input)?;
@ -409,11 +408,10 @@ impl ToCss for System {
}
/// <https://drafts.csswg.org/css-counter-styles/#typedef-symbol>
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss, ToShmem)]
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss, ToShmem, MallocSizeOf)]
pub enum Symbol {
/// <string>
String(String),
String(crate::OwnedStr),
/// <custom-ident>
Ident(CustomIdent),
// Not implemented:
@ -428,7 +426,7 @@ impl Parse for Symbol {
) -> Result<Self, ParseError<'i>> {
let location = input.current_source_location();
match *input.next()? {
Token::QuotedString(ref s) => Ok(Symbol::String(s.as_ref().to_owned())),
Token::QuotedString(ref s) => Ok(Symbol::String(s.as_ref().to_owned().into())),
Token::Ident(ref s) => Ok(Symbol::Ident(CustomIdent::from_ident(location, s, &[])?)),
ref t => Err(location.new_unexpected_token_error(t.clone())),
}
@ -463,12 +461,25 @@ impl Parse for Negative {
}
/// <https://drafts.csswg.org/css-counter-styles/#counter-style-range>
///
/// Empty Vec represents 'auto'
#[derive(Clone, Debug, ToShmem)]
pub struct Ranges(pub Vec<Range<CounterBound>>);
#[derive(Clone, Debug, ToShmem, ToCss)]
pub struct CounterRange {
/// The start of the range.
pub start: CounterBound,
/// The end of the range.
pub end: CounterBound,
}
/// A bound found in `Ranges`.
/// <https://drafts.csswg.org/css-counter-styles/#counter-style-range>
///
/// Empty represents 'auto'
#[derive(Clone, Debug, ToShmem, ToCss)]
#[css(comma)]
pub struct CounterRanges(
#[css(iterable, if_empty = "auto")]
pub crate::OwnedSlice<CounterRange>,
);
/// A bound found in `CounterRanges`.
#[derive(Clone, Copy, Debug, ToCss, ToShmem)]
pub enum CounterBound {
/// An integer bound.
@ -477,7 +488,7 @@ pub enum CounterBound {
Infinite,
}
impl Parse for Ranges {
impl Parse for CounterRanges {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
@ -486,25 +497,25 @@ impl Parse for Ranges {
.try(|input| input.expect_ident_matching("auto"))
.is_ok()
{
Ok(Ranges(Vec::new()))
} else {
input
.parse_comma_separated(|input| {
let opt_start = parse_bound(context, input)?;
let opt_end = parse_bound(context, input)?;
if let (CounterBound::Integer(start), CounterBound::Integer(end)) =
(opt_start, opt_end)
{
if start > end {
return Err(
input.new_custom_error(StyleParseErrorKind::UnspecifiedError)
);
}
}
Ok(opt_start..opt_end)
})
.map(Ranges)
return Ok(CounterRanges(Default::default()));
}
let ranges = input.parse_comma_separated(|input| {
let start = parse_bound(context, input)?;
let end = parse_bound(context, input)?;
if let (CounterBound::Integer(start), CounterBound::Integer(end)) =
(start, end)
{
if start > end {
return Err(
input.new_custom_error(StyleParseErrorKind::UnspecifiedError)
);
}
}
Ok(CounterRange { start, end })
})?;
Ok(CounterRanges(ranges.into()))
}
}
@ -519,34 +530,6 @@ fn parse_bound<'i, 't>(
Ok(CounterBound::Infinite)
}
impl ToCss for Ranges {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
let mut iter = self.0.iter();
if let Some(first) = iter.next() {
range_to_css(first, dest)?;
for item in iter {
dest.write_str(", ")?;
range_to_css(item, dest)?;
}
Ok(())
} else {
dest.write_str("auto")
}
}
}
fn range_to_css<W>(range: &Range<CounterBound>, dest: &mut CssWriter<W>) -> fmt::Result
where
W: Write,
{
range.start.to_css(dest)?;
dest.write_char(' ')?;
range.end.to_css(dest)
}
/// <https://drafts.csswg.org/css-counter-styles/#counter-style-pad>
#[derive(Clone, Debug, ToCss, ToShmem)]
pub struct Pad(pub Integer, pub Symbol);
@ -572,14 +555,13 @@ impl Parse for Fallback {
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
parse_counter_style_name(input).map(Fallback)
Ok(Fallback(parse_counter_style_name(input)?))
}
}
/// <https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-symbols>
#[cfg_attr(feature = "gecko", derive(MallocSizeOf))]
#[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss, ToShmem)]
pub struct Symbols(#[css(iterable)] pub Vec<Symbol>);
#[derive(Clone, Debug, Eq, PartialEq, MallocSizeOf, ToComputedValue, ToCss, ToShmem)]
pub struct Symbols(#[css(iterable)] pub crate::OwnedSlice<Symbol>);
impl Parse for Symbols {
fn parse<'i, 't>(
@ -587,23 +569,20 @@ impl Parse for Symbols {
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
let mut symbols = Vec::new();
loop {
if let Ok(s) = input.try(|input| Symbol::parse(context, input)) {
symbols.push(s)
} else {
if symbols.is_empty() {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
} else {
return Ok(Symbols(symbols));
}
}
while let Ok(s) = input.try(|input| Symbol::parse(context, input)) {
symbols.push(s);
}
if symbols.is_empty() {
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
}
Ok(Symbols(symbols.into()))
}
}
/// <https://drafts.csswg.org/css-counter-styles/#descdef-counter-style-additive-symbols>
#[derive(Clone, Debug, ToCss, ToShmem)]
pub struct AdditiveSymbols(pub Vec<AdditiveTuple>);
#[css(comma)]
pub struct AdditiveSymbols(#[css(iterable)] pub crate::OwnedSlice<AdditiveTuple>);
impl Parse for AdditiveSymbols {
fn parse<'i, 't>(
@ -618,7 +597,7 @@ impl Parse for AdditiveSymbols {
{
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
}
Ok(AdditiveSymbols(tuples))
Ok(AdditiveSymbols(tuples.into()))
}
}
@ -643,10 +622,7 @@ impl Parse for AdditiveTuple {
let symbol = input.try(|input| Symbol::parse(context, input));
let weight = Integer::parse_non_negative(context, input)?;
let symbol = symbol.or_else(|_| Symbol::parse(context, input))?;
Ok(AdditiveTuple {
weight: weight,
symbol: symbol,
})
Ok(Self { weight, symbol })
}
}

View file

@ -288,7 +288,7 @@ impl CounterStyleOrNone {
.0
.iter()
.map(|symbol| match *symbol {
Symbol::String(ref s) => nsCStr::from(s),
Symbol::String(ref s) => nsCStr::from(&**s),
Symbol::Ident(_) => unreachable!("Should not have identifier in symbols()"),
})
.collect();
@ -333,7 +333,7 @@ impl CounterStyleOrNone {
let symbol_type = SymbolsType::from_gecko_keyword(anonymous.mSystem as u32);
let symbols = symbols
.iter()
.map(|gecko_symbol| Symbol::String(gecko_symbol.to_string()))
.map(|gecko_symbol| Symbol::String(gecko_symbol.to_string().into()))
.collect();
Either::First(CounterStyleOrNone::Symbols(symbol_type, Symbols(symbols)))
}