1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
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))
}
}