css_lexer/quote_style.rs
1use core::fmt;
2
3/// An enum representing the "Style" the [Kind::String][crate::Kind::String] token represents.
4///
5/// A [Token][crate::Token] with [Kind::String][crate::Kind::String] will store this data internal to the token. Using
6/// [Token::quote_style()][crate::Token::quote_style()] will return this enum, depending on what character is used to
7/// represent the [Kind::String][crate::Kind::String] token.
8/// ```
9/// use css_lexer::*;
10/// let mut lexer = Lexer::new("/* Normal Comment */ /** Double Star Comment */");
11/// {
12/// // This token will be collapsed Whitespace.
13/// let token = lexer.advance();
14/// assert_eq!(token, Kind::Comment);
15/// assert_eq!(token, CommentStyle::Block);
16/// }
17/// assert_eq!(lexer.advance(), Kind::Whitespace);
18/// {
19/// // This token will be collapsed Whitespace.
20/// let token = lexer.advance();
21/// assert_eq!(token, Kind::Comment);
22/// assert_eq!(token, CommentStyle::BlockStar);
23/// }
24/// ```
25#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(tag = "kind", content = "value"))]
27pub enum QuoteStyle {
28 /// Tokens such as [Kind::Url][crate::Kind::Url] may also refer to [QuoteStyle], but a URL is not required to contain
29 /// quote characters, as the parenthesese are sufficient to disambiguate the token. In these case the
30 /// [QuoteStyle::None] variant exists to encode this information. [Kind::String][crate::Kind::String] tokens must
31 /// always have a quote style that is not [QuoteStyle::None].
32 None,
33 /// The single quote character or APOSTROPHE (`'`) was used.
34 Single,
35 #[default]
36 /// The double quote character or QUOTATION MARK (`"`) was used.
37 Double,
38}
39
40impl QuoteStyle {
41 const fn as_char(&self) -> Option<char> {
42 match self {
43 Self::Single => Some('\''),
44 Self::Double => Some('"'),
45 Self::None => None,
46 }
47 }
48}
49
50impl fmt::Display for QuoteStyle {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 if let Some(ch) = self.as_char() {
53 fmt::Display::fmt(&ch, f)?;
54 }
55 Ok(())
56 }
57}
58
59impl PartialEq<char> for QuoteStyle {
60 fn eq(&self, other: &char) -> bool {
61 self.as_char().map(|char| char == *other).unwrap_or(false)
62 }
63}
64
65#[test]
66fn size_test() {
67 assert_eq!(::std::mem::size_of::<QuoteStyle>(), 1);
68}
69
70#[test]
71fn test_partial_eq() {
72 assert!(QuoteStyle::Single == '\'');
73 assert!(QuoteStyle::Double == '"');
74 assert!(QuoteStyle::Single != '"');
75 assert!(QuoteStyle::Double != '\'');
76}