less-rs 0.0.0

A Rust implementation of the Less CSS preprocessor.
Documentation
use std::fmt;

use cssparser::{BasicParseErrorKind, ParseError, Parser, ParserState};
use less_allocator::Allocator;

use crate::{
  error::ParserError,
  printer::{Printer, PrinterError},
};

pub trait Parse<'i>: Sized {
  fn parse<'t>(
    allocator: &'i Allocator,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self, ParseError<'i, ParserError<'i>>>;
}

/// Trait for things the can serialize themselves in CSS syntax.
pub trait ToCss<'i> {
  /// Serialize `self` in CSS syntax, writing to `dest`.
  fn to_css<W>(&self, dest: &mut Printer<'_, 'i, W>) -> Result<(), PrinterError<'i>>
  where
    W: fmt::Write;

  /// Serialize `self` in CSS syntax and return a string.
  ///
  /// (This is a convenience wrapper for `to_css` and probably should not be overridden.)
  #[inline]
  fn to_css_string(&self, allocator: &'i Allocator) -> Result<String, PrinterError<'i>> {
    let mut s = String::new();
    let mut printer = Printer::new(allocator, &mut s);
    self.to_css(&mut printer)?;
    dbg!(&printer.col, &printer.line);
    Ok(s)
  }
}

pub trait AtRuleParser<'i> {
  /// The intermediate representation of prelude of an at-rule.
  type Prelude;

  /// The finished representation of an at-rule.
  type AtRule;

  /// The error type that is included in the ParseError value that can be returned.
  type Error: 'i;

  /// Parse the prelude of an at-rule with the given `name`.
  ///
  /// Return the representation of the prelude and the type of at-rule,
  /// or an `Err(..)` to ignore the entire at-rule as invalid.
  ///
  /// The prelude is the part after the at-keyword
  /// and before the `;` semicolon or `{ /* ... */ }` block.
  ///
  /// At-rule name matching should be case-insensitive in the ASCII range.
  /// This can be done with `std::ascii::Ascii::eq_ignore_ascii_case`,
  /// or with the `match_ignore_ascii_case!` macro.
  ///
  /// The given `input` is a "delimited" parser
  /// that ends wherever the prelude should end.
  /// (Before the next semicolon, the next `{`, or the end of the current block.)
  fn parse_prelude<'t>(
    &mut self,
    allocator: &'i Allocator,
    name: cssparser::CowRcStr<'i>,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::Prelude, ParseError<'i, Self::Error>> {
    let _ = allocator;
    Err(input.new_error(BasicParseErrorKind::AtRuleInvalid(name)))
  }

  /// End an at-rule which doesn't have block. Return the finished
  /// representation of the at-rule.
  ///
  /// The location passed in is source location of the start of the prelude.
  ///
  /// This is only called when `parse_prelude` returned `WithoutBlock`, and
  /// either the `;` semicolon indeed follows the prelude, or parser is at
  /// the end of the input.
  #[allow(clippy::result_unit_err)]
  fn rule_without_block(
    &mut self,
    allocator: &'i Allocator,
    prelude: Self::Prelude,
    start: &ParserState,
  ) -> Result<Self::AtRule, ()> {
    let _ = allocator;
    let _ = prelude;
    let _ = start;
    Err(())
  }

  /// Parse the content of a `{ /* ... */ }` block for the body of the at-rule.
  ///
  /// The location passed in is source location of the start of the prelude.
  ///
  /// Return the finished representation of the at-rule
  /// as returned by `RuleListParser::next` or `DeclarationListParser::next`,
  /// or an `Err(..)` to ignore the entire at-rule as invalid.
  ///
  /// This is only called when `parse_prelude` returned `WithBlock`, and a block
  /// was indeed found following the prelude.
  fn parse_block<'t>(
    &mut self,
    allocator: &'i Allocator,
    prelude: Self::Prelude,
    start: &ParserState,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::AtRule, ParseError<'i, Self::Error>> {
    let _ = allocator;
    let _ = prelude;
    let _ = start;
    Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid))
  }
}

pub trait QualifiedRuleParser<'i> {
  /// The intermediate representation of a qualified rule prelude.
  type Prelude;

  /// The finished representation of a qualified rule.
  type QualifiedRule;

  /// The error type that is included in the ParseError value that can be returned.
  type Error: 'i;

  /// Parse the prelude of a qualified rule. For style rules, this is as Selector list.
  ///
  /// Return the representation of the prelude,
  /// or an `Err(..)` to ignore the entire at-rule as invalid.
  ///
  /// The prelude is the part before the `{ /* ... */ }` block.
  ///
  /// The given `input` is a "delimited" parser
  /// that ends where the prelude should end (before the next `{`).
  fn parse_prelude<'t>(
    &mut self,
    allocator: &'i Allocator,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::Prelude, ParseError<'i, Self::Error>> {
    let _ = allocator;
    Err(input.new_error(BasicParseErrorKind::QualifiedRuleInvalid))
  }

  /// Parse the content of a `{ /* ... */ }` block for the body of the qualified rule.
  ///
  /// The location passed in is source location of the start of the prelude.
  ///
  /// Return the finished representation of the qualified rule
  /// as returned by `RuleListParser::next`,
  /// or an `Err(..)` to ignore the entire at-rule as invalid.
  fn parse_block<'t>(
    &mut self,
    allocator: &'i Allocator,
    prelude: Self::Prelude,
    start: &ParserState,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::QualifiedRule, ParseError<'i, Self::Error>> {
    let _ = allocator;
    let _ = prelude;
    let _ = start;
    Err(input.new_error(BasicParseErrorKind::QualifiedRuleInvalid))
  }
}