css_parse/feature.rs
1use bitmask_enum::bitmask;
2
3/// A set of runtime feature flags which can be enabled individually or in combination, which will change the way
4/// [Parser][crate::Parser] works.
5///
6/// To build multiple features, use the bitwise OR operator.
7///
8/// # Example
9///
10/// ```
11/// use css_parse::*;
12/// use bumpalo::Bump;
13/// let bump = Bump::default();
14/// let features = Feature::SingleLineComments | Feature::SeparateWhitespace;
15/// let mut parser = Parser::new_with_features(&bump, "// foo", features);
16/// ```
17#[bitmask(u8)]
18pub enum Feature {
19 /// This flag is forwarded to the [Lexer][css_lexer::Lexer] which, when enabled, will treat single line comments as valid
20 /// Comment tokens. If it encounters two consecutative SOLIDUS characters (`//`), it will return a
21 /// [Token][crate::Token] with [Kind::Comment][crate::Kind::Comment]. For more information about exactly what
22 /// happens here at the lexer level, consult the [crate::Feature::SingleLineComments] feature.
23 ///
24 /// This flag doesn't cause any changes in logic on the [Parser][crate::Parser]; comments will be collected in the
25 /// trivia tokens Vec as normal.
26 SingleLineComments,
27
28 /// This flag is forwarded to the [Lexer][css_lexer::Lexer] which, when enabled, will treat diffetent whitespace kinds as
29 /// descrete. For more information about exactly what happens here at the lexer level, consult the
30 /// [crate::Feature::SeparateWhitespace] feature.
31 ///
32 /// This flag doesn't cause any changes in logic on the [Parser][crate::Parser]; whitespace is typically collected in
33 /// the trivia Vec. AST nodes which call [Parser::set_skip()][crate::Parser::set_skip] to parse whitespace sensitive nodes
34 /// should be cognizant that this feature could be enabled, meaning that adjacent whitespace tokens are possible. To
35 /// counter adjacent tokens, simply parse any whitespace in a loop.
36 SeparateWhitespace,
37}
38
39impl From<Feature> for css_lexer::Feature {
40 fn from(value: Feature) -> Self {
41 let mut f = Self::none();
42 if value.contains(Feature::SingleLineComments) {
43 f |= Self::SingleLineComments
44 }
45 if value.contains(Feature::SeparateWhitespace) {
46 f |= Self::SeparateWhitespace
47 }
48 f
49 }
50}
51
52impl Default for Feature {
53 fn default() -> Self {
54 Self::none()
55 }
56}