css_lexer/
pairwise.rs

1use crate::{Kind, Token};
2
3/// Represents either the left or right [Kind] of a [PairWise] set.
4///
5/// Certain kinds have a [PairWise] equivalent:
6///  - [Kind::LeftParen] has [Kind::RightParen]
7///  - [Kind::LeftCurly] has [Kind::RightCurly]
8///  - [Kind::LeftSquare] has [Kind::RightSquare]
9///
10/// The [PairWise] enum represents either one of the above listed [Kinds][Kind]. So for example [PairWise::Paren]
11/// represents both the [Kind::LeftParen] and [Kind::RightParen].
12///
13/// # Example
14///
15/// ```
16/// use css_lexer::*;
17/// let mut lexer = Lexer::new("(a)");
18/// {
19///     let token = lexer.advance();
20///     assert_eq!(token, PairWise::Paren);
21///     assert_eq!(token, Kind::LeftParen);
22///     let pair: PairWise = token.to_pairwise().unwrap();
23///     let mut close_token;
24///     loop {
25///         close_token = lexer.advance();
26///         if close_token == pair {
27///             break;
28///         }
29///     }
30///     assert_eq!(close_token, Kind::RightParen);
31/// }
32/// ```
33#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize))]
35pub enum PairWise {
36	Paren,
37	Curly,
38	Square,
39}
40
41impl PairWise {
42	pub fn from_token(token: &Token) -> Option<Self> {
43		match token.kind() {
44			Kind::LeftParen | Kind::Function => Some(Self::Paren),
45			Kind::LeftCurly => Some(Self::Curly),
46			Kind::LeftSquare => Some(Self::Square),
47			Kind::RightParen => Some(Self::Paren),
48			Kind::RightCurly => Some(Self::Curly),
49			Kind::RightSquare => Some(Self::Square),
50			_ => None,
51		}
52	}
53
54	pub fn start(&self) -> Token {
55		match self {
56			Self::Paren => Token::LEFT_PAREN,
57			Self::Curly => Token::LEFT_CURLY,
58			Self::Square => Token::LEFT_SQUARE,
59		}
60	}
61
62	pub fn end(&self) -> Token {
63		match self {
64			Self::Paren => Token::RIGHT_PAREN,
65			Self::Curly => Token::RIGHT_CURLY,
66			Self::Square => Token::RIGHT_SQUARE,
67		}
68	}
69}
70
71impl PartialEq<Kind> for PairWise {
72	fn eq(&self, other: &Kind) -> bool {
73		self.end() == *other || self.start() == *other
74	}
75}
76
77#[test]
78fn test_partial_eq_kind() {
79	assert_eq!(PairWise::Paren, Kind::LeftParen);
80	assert_eq!(PairWise::Paren, Kind::RightParen);
81	assert_eq!(PairWise::Square, Kind::LeftSquare);
82	assert_eq!(PairWise::Square, Kind::RightSquare);
83	assert_eq!(PairWise::Curly, Kind::LeftCurly);
84	assert_eq!(PairWise::Curly, Kind::RightCurly);
85}