Introduce Separator::parse

This commit is contained in:
Anthony Ramine 2017-06-27 10:30:48 +02:00
parent 6c17bb03ce
commit 17875b8a81
6 changed files with 59 additions and 26 deletions

View file

@ -19,7 +19,7 @@ use std::ascii::AsciiExt;
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt; use std::fmt;
use std::ops::Range; use std::ops::Range;
use style_traits::{ToCss, OneOrMoreSeparated, CommaSeparator, ParseError, StyleParseError}; use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss};
use values::CustomIdent; use values::CustomIdent;
/// Parse the prelude of an @counter-style rule /// Parse the prelude of an @counter-style rule
@ -553,7 +553,7 @@ pub struct AdditiveTuple {
} }
impl OneOrMoreSeparated for AdditiveTuple { impl OneOrMoreSeparated for AdditiveTuple {
type S = CommaSeparator; type S = Comma;
} }
impl Parse for AdditiveTuple { impl Parse for AdditiveTuple {

View file

@ -22,7 +22,7 @@ use properties::longhands::font_language_override;
use selectors::parser::SelectorParseError; use selectors::parser::SelectorParseError;
use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
use std::fmt; use std::fmt;
use style_traits::{ToCss, OneOrMoreSeparated, CommaSeparator, ParseError, StyleParseError}; use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss};
use values::specified::url::SpecifiedUrl; use values::specified::url::SpecifiedUrl;
/// A source for a font-face rule. /// A source for a font-face rule.
@ -37,7 +37,7 @@ pub enum Source {
} }
impl OneOrMoreSeparated for Source { impl OneOrMoreSeparated for Source {
type S = CommaSeparator; type S = Comma;
} }
/// A `UrlSource` represents a font-face source that has been specified with a /// A `UrlSource` represents a font-face source that has been specified with a

View file

@ -7,7 +7,7 @@
use context::QuirksMode; use context::QuirksMode;
use cssparser::{Parser, SourcePosition, UnicodeRange}; use cssparser::{Parser, SourcePosition, UnicodeRange};
use error_reporting::{ParseErrorReporter, ContextualParseError}; use error_reporting::{ParseErrorReporter, ContextualParseError};
use style_traits::{OneOrMoreSeparated, IsCommaSeparator, ParseError, ParsingMode}; use style_traits::{OneOrMoreSeparated, ParseError, ParsingMode, Separator};
#[cfg(feature = "gecko")] #[cfg(feature = "gecko")]
use style_traits::{PARSING_MODE_DEFAULT, PARSING_MODE_ALLOW_UNITLESS_LENGTH, PARSING_MODE_ALLOW_ALL_NUMERIC_VALUES}; use style_traits::{PARSING_MODE_DEFAULT, PARSING_MODE_ALLOW_UNITLESS_LENGTH, PARSING_MODE_ALLOW_ALL_NUMERIC_VALUES};
use stylesheets::{CssRuleType, Origin, UrlExtraData, Namespaces}; use stylesheets::{CssRuleType, Origin, UrlExtraData, Namespaces};
@ -161,12 +161,14 @@ pub trait Parse : Sized {
-> Result<Self, ParseError<'i>>; -> Result<Self, ParseError<'i>>;
} }
impl<T> Parse for Vec<T> where T: Parse + OneOrMoreSeparated, impl<T> Parse for Vec<T>
<T as OneOrMoreSeparated>::S: IsCommaSeparator where
T: Parse + OneOrMoreSeparated,
<T as OneOrMoreSeparated>::S: Separator,
{ {
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-> Result<Self, ParseError<'i>> { -> Result<Self, ParseError<'i>> {
input.parse_comma_separated(|input| T::parse(context, input)) <T as OneOrMoreSeparated>::S::parse(input, |i| T::parse(context, i))
} }
} }

View file

@ -9,7 +9,7 @@ use counter_style::{Symbols, parse_counter_style_name};
use cssparser::Parser; use cssparser::Parser;
use parser::{Parse, ParserContext}; use parser::{Parse, ParserContext};
use std::fmt; use std::fmt;
use style_traits::{OneOrMoreSeparated, CommaSeparator, ToCss, ParseError, StyleParseError}; use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseError, ToCss};
use super::CustomIdent; use super::CustomIdent;
use values::specified::url::SpecifiedUrl; use values::specified::url::SpecifiedUrl;
@ -125,7 +125,7 @@ pub struct FontSettingTag<T> {
} }
impl<T> OneOrMoreSeparated for FontSettingTag<T> { impl<T> OneOrMoreSeparated for FontSettingTag<T> {
type S = CommaSeparator; type S = Comma;
} }
impl<T: ToCss> ToCss for FontSettingTag<T> { impl<T: ToCss> ToCss for FontSettingTag<T> {

View file

@ -71,7 +71,7 @@ pub mod values;
#[macro_use] #[macro_use]
pub mod viewport; pub mod viewport;
pub use values::{ToCss, OneOrMoreSeparated, CommaSeparator, SpaceSeparator, IsCommaSeparator}; pub use values::{Comma, OneOrMoreSeparated, Separator, Space, ToCss};
pub use viewport::HasViewportPercentage; pub use viewport::HasViewportPercentage;
/// The error type for all CSS parsing routines. /// The error type for all CSS parsing routines.

View file

@ -5,7 +5,7 @@
//! Helper types and traits for the handling of CSS values. //! Helper types and traits for the handling of CSS values.
use app_units::Au; use app_units::Au;
use cssparser::{UnicodeRange, serialize_string}; use cssparser::{ParseError, Parser, UnicodeRange, serialize_string};
use std::fmt::{self, Write}; use std::fmt::{self, Write};
/// Serialises a value according to its CSS representation. /// Serialises a value according to its CSS representation.
@ -184,38 +184,69 @@ where
/// Type used as the associated type in the `OneOrMoreSeparated` trait on a /// Type used as the associated type in the `OneOrMoreSeparated` trait on a
/// type to indicate that a serialized list of elements of this type is /// type to indicate that a serialized list of elements of this type is
/// separated by commas. /// separated by commas.
pub struct CommaSeparator; pub struct Comma;
/// Type used as the associated type in the `OneOrMoreSeparated` trait on a /// Type used as the associated type in the `OneOrMoreSeparated` trait on a
/// type to indicate that a serialized list of elements of this type is /// type to indicate that a serialized list of elements of this type is
/// separated by spaces. /// separated by spaces.
pub struct SpaceSeparator; pub struct Space;
/// A trait satisfied by the types corresponding to separators. /// A trait satisfied by the types corresponding to separators.
pub trait Separator { pub trait Separator {
/// The separator string that the satisfying separator type corresponds to. /// The separator string that the satisfying separator type corresponds to.
fn separator() -> &'static str; fn separator() -> &'static str;
/// Parses a sequence of values separated by this separator.
///
/// The given closure is called repeatedly for each item in the sequence.
///
/// Successful results are accumulated in a vector.
///
/// This method returns `Err(_)` the first time a closure does or if
/// the separators aren't correct.
fn parse<'i, 't, F, T, E>(
parser: &mut Parser<'i, 't>,
parse_one: F,
) -> Result<Vec<T>, ParseError<'i, E>>
where
F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>;
} }
impl Separator for CommaSeparator { impl Separator for Comma {
fn separator() -> &'static str { fn separator() -> &'static str {
", " ", "
} }
}
impl Separator for SpaceSeparator { fn parse<'i, 't, F, T, E>(
fn separator() -> &'static str { input: &mut Parser<'i, 't>,
" " parse_one: F,
) -> Result<Vec<T>, ParseError<'i, E>>
where
F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>
{
input.parse_comma_separated(parse_one)
} }
} }
/// Trait that indicates that satisfying separator types are comma separators. impl Separator for Space {
/// This seems kind of redundant, but we aren't able to express type equality fn separator() -> &'static str {
/// constraints yet. " "
/// https://github.com/rust-lang/rust/issues/20041 }
pub trait IsCommaSeparator {}
impl IsCommaSeparator for CommaSeparator {} fn parse<'i, 't, F, T, E>(
input: &mut Parser<'i, 't>,
mut parse_one: F,
) -> Result<Vec<T>, ParseError<'i, E>>
where
F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>
{
let mut results = vec![parse_one(input)?];
while let Ok(item) = input.try(&mut parse_one) {
results.push(item);
}
Ok(results)
}
}
/// Marker trait on T to automatically implement ToCss for Vec<T> when T's are /// Marker trait on T to automatically implement ToCss for Vec<T> when T's are
/// separated by some delimiter `delim`. /// separated by some delimiter `delim`.
@ -225,7 +256,7 @@ pub trait OneOrMoreSeparated {
} }
impl OneOrMoreSeparated for UnicodeRange { impl OneOrMoreSeparated for UnicodeRange {
type S = CommaSeparator; type S = Comma;
} }
impl<T> ToCss for Vec<T> where T: ToCss + OneOrMoreSeparated { impl<T> ToCss for Vec<T> where T: ToCss + OneOrMoreSeparated {