Trait RangedFeature

Source
pub trait RangedFeature<'a>: Sized {
    type Value: Parse<'a>;

    // Required methods
    fn new_exact(
        open: LeftParen,
        name: Ident,
        colon: Colon,
        value: Self::Value,
        close: RightParen,
    ) -> ParserResult<Self>;
    fn new_left(
        open: LeftParen,
        name: Ident,
        comparison: Comparison,
        value: Self::Value,
        close: RightParen,
    ) -> ParserResult<Self>;
    fn new_right(
        open: LeftParen,
        value: Self::Value,
        comparison: Comparison,
        name: Ident,
        close: RightParen,
    ) -> ParserResult<Self>;
    fn new_ranged(
        open: LeftParen,
        left: Self::Value,
        left_comparison: Comparison,
        name: Ident,
        right_comparison: Comparison,
        value: Self::Value,
        close: RightParen,
    ) -> ParserResult<Self>;

    // Provided methods
    fn new_max(
        _open: LeftParen,
        name: Ident,
        _colon: Colon,
        _value: Self::Value,
        _close: RightParen,
    ) -> ParserResult<Self> { ... }
    fn new_min(
        _open: LeftParen,
        name: Ident,
        _colon: Colon,
        _value: Self::Value,
        _close: RightParen,
    ) -> ParserResult<Self> { ... }
    fn parse_ranged_feature<I, A: AtomSet + PartialEq>(
        p: &mut Parser<'a, I>,
        name: &A,
        min: Option<&A>,
        max: Option<&A>,
    ) -> ParserResult<Self>
       where I: Iterator<Item = Cursor> + Clone { ... }
}
Expand description

This trait provides an implementation for parsing a “Media Feature” in the “Range” context.

Rather than implementing this trait on an enum, use the ranged_feature! macro which expands to define the enum and necessary traits (Parse, this trait, and ToCursors) in a single macro call.

It does not implement Parse, but provides parse_ranged_feature(&mut Parser<'a>) -> Result<Self>, which can make for a trivial Parse implementation. The type Self::Value represents the <value> token(s). The grammar of both <value> isn’t mandated by this spec but is very likely a Dimension or Number. The <feature-name> is determined by the three given arguments to parse_ranged_feature - each must implement AtomSet, so they can be compared to the given ident atom in that position. Passing the third and fourth arguments for min & max atoms allows the “legacy” min/max variants to be parsed also.

CSS defines the Media Feature in Ranged context as:

                                          ╭─ "="  ─╮
                                          ├─ "<"  ─┤
                                          ├─ "<=" ─┤
                                          ├─ ">"  ─┤
 │├─ "(" ─╮─ [<feature-name> or <value>] ─╯─ ">=" ─╰─ [<feature-name> or <value>] ─╭─ ")" ─┤│
          ├────── <value> ─╮─ "<"  ─╭── <feature-name> ─╮─ "<"  ─╭── <value> ──────┤
          │                ╰─ "<=" ─╯                   ╰─ "<=" ─╯                 │
          ╰────── <value> ─╮─ ">"  ─╭── <feature-name> ─╮─ ">"  ─╭── <value> ──────╯
                           ╰─ ">=" ─╯                   ╰─ ">=" ─╯

This trait deviates slightly from the CSS spec ever so slightly for a few reasons:

  • It uses a <comparison> token to represent each of the comparison operators, implemented as Comparison. This makes for much more convenient parsing and subsequent analyses.
  • The CSS defined railroad diagram doesn’t quite fully convey that <value> <comparison> <value> and <feature-name> <comparison> <feature-name> are not valid productions. This trait will fail to parse such productions, as do all existing implementations of CSS (i.e browsers).
  • It does not do the extra validation to ensure a left/right comparison are “directionally equivalent” - in other words <value> "<=" <feature-name> "=>" <value> is a valid production in this trait - this allows for ASTs to factor in error tolerance. If an AST node wishes to be strict, it can check the comparators inside of RangedFeature::new_ranged and return an Err there.
  • It supports the “Legacy” modes which are defined for certain ranged media features. These legacy productions use a colon token and typically have min and max variants. For example width: 1024px is equivalent to width >= 1024px, while max-width: 1024px is equivalent to max-width <= 1024px. If an AST node wishes to not support legacy feature-names, it can supply Nones to RangedFeature::parse_ranged_feature.

Given the above differences, the trait RangedFeature parses a grammar defined as:

<comparison>
 │├──╮─ "="  ─╭──┤│
     ├─ "<"  ─┤
     ├─ "<=" ─┤
     ├─ ">"  ─┤
     ╰─ ">=" ─╯

<ranged-feature-trait>
 │├─ "(" ─╮─ <feature-name> ─ <comparison> ─ <value> ─────────────────────────────────╭─ ")" ─┤│
          ├─ <value> ─ <comparison> ─ <ranged-feautre-name> ──────────────────────────┤
          ├─ <value> ─ <comparison> ─ <ranged-feature-name> ─ <comparison> ─ <value> ─┤
          ╰─ <feature-name> ─ ":" ─ <value> ──────────────────────────────────────────╯

Required Associated Types§

Source

type Value: Parse<'a>

Required Methods§

Source

fn new_exact( open: LeftParen, name: Ident, colon: Colon, value: Self::Value, close: RightParen, ) -> ParserResult<Self>

Method for constructing a “exact” media feature. Exact features always include a colon token.

Source

fn new_left( open: LeftParen, name: Ident, comparison: Comparison, value: Self::Value, close: RightParen, ) -> ParserResult<Self>

Method for constructing a “left” media feature. This method is called when the parsed tokens encountered the <value> token before the <feature-name>.

Source

fn new_right( open: LeftParen, value: Self::Value, comparison: Comparison, name: Ident, close: RightParen, ) -> ParserResult<Self>

Method for constructing a “right” media feature. This method is called when the parsed tokens encountered the <feature-name> token before the <value>.

Source

fn new_ranged( open: LeftParen, left: Self::Value, left_comparison: Comparison, name: Ident, right_comparison: Comparison, value: Self::Value, close: RightParen, ) -> ParserResult<Self>

Method for constructing a “ranged” media feature. This method is called when the parsed tokens encountered the <value> token, followed by a <comparison>, followed by a <feature-name>, followed by a <comparison> followed lastly by a <value>.

Provided Methods§

Source

fn new_max( _open: LeftParen, name: Ident, _colon: Colon, _value: Self::Value, _close: RightParen, ) -> ParserResult<Self>

Method for constructing a “legacy max” media feature. Legacy features always include a colon token.

Source

fn new_min( _open: LeftParen, name: Ident, _colon: Colon, _value: Self::Value, _close: RightParen, ) -> ParserResult<Self>

Method for constructing a “legacy min” media feature. Legacy features always include a colon token.

Source

fn parse_ranged_feature<I, A: AtomSet + PartialEq>( p: &mut Parser<'a, I>, name: &A, min: Option<&A>, max: Option<&A>, ) -> ParserResult<Self>
where I: Iterator<Item = Cursor> + Clone,

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§