css_lexer/whitespace_style.rs
1use bitmask_enum::bitmask;
2
3/// A [bitmask][bitmask_enum] representing the characters that make up a [Kind::Whitespace][crate::Kind::Whitespace]
4/// token.
5///
6/// A [Token][crate::Token] with [Kind::Whitespace][crate::Kind::Whitespace] will store this data internal to the
7/// token. Using [Token::whitespace_style()][crate::Token::whitespace_style()] will return this bitmask, depending on
8/// what characters make up the whitespace token. By default the [Lexer][crate::Lexer] will produce combine multiple
9/// whitespaces into a single [Token][crate::Token], so it is possible that
10/// [Token::whitespace_style()][crate::Token::whitespace_style()] could contain all of the available bits here. With
11/// [Feature::SeparateWhitespace][crate::Feature::SeparateWhitespace] the [Lexer][crate::Lexer] will produce discrete
12/// tokens each which can only have one of the available bits in this bitmask.
13///
14/// ```
15/// use css_lexer::*;
16/// let mut lexer = Lexer::new("\n\t");
17/// {
18/// // This token will be collapsed Whitespace.
19/// let token = lexer.advance();
20/// assert_eq!(token, Kind::Whitespace);
21/// // The Whitespace is comprised of many bits:
22/// assert_eq!(token, Whitespace::Newline | Whitespace::Tab);
23/// }
24/// ```
25#[bitmask(u8)]
26#[bitmask_config(vec_debug)]
27pub enum Whitespace {
28 /// The whitespace token contains at least 1 Space (` `) character.
29 Space = 0b001,
30 /// The whitespace token contains at least 1 Tab (`\t`) character.
31 Tab = 0b010,
32 /// The whitespace token contains at least 1 Newline (`\n`) or newline-adjacent (`\r`, `\r\n`, `\u{c}`) character.
33 Newline = 0b100,
34}
35
36impl Whitespace {
37 pub(crate) const fn from_bits(bits: u8) -> Self {
38 Self { bits: bits & 0b111 }
39 }
40
41 pub(crate) const fn to_bits(self) -> u8 {
42 self.bits
43 }
44}
45
46#[test]
47fn size_test() {
48 assert_eq!(::std::mem::size_of::<Whitespace>(), 1);
49}
50
51#[test]
52fn test_from_bits() {
53 assert!(Whitespace::from_bits(Whitespace::Space.bits).contains(Whitespace::Space));
54 assert!(Whitespace::from_bits(Whitespace::Tab.bits).contains(Whitespace::Tab));
55 assert!(Whitespace::from_bits(Whitespace::Newline.bits).contains(Whitespace::Newline));
56}