#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[allow(non_camel_case_types)]
pub enum SyntaxKind {
WHITESPACE = 0,
NEWLINE,
COMMENT,
IDENT,
ARGUMENT,
DOUBLE_QUOTED_STRING,
SINGLE_QUOTED_STRING,
VARIABLE,
SEMICOLON,
L_BRACE,
R_BRACE,
RAW_CONTENT,
ERROR,
ROOT,
DIRECTIVE,
BLOCK,
BLANK_LINE,
}
impl SyntaxKind {
pub fn is_trivia(self) -> bool {
matches!(self, Self::WHITESPACE | Self::NEWLINE | Self::COMMENT)
}
fn to_raw(self) -> u16 {
match self {
Self::WHITESPACE => 0,
Self::NEWLINE => 1,
Self::COMMENT => 2,
Self::IDENT => 3,
Self::ARGUMENT => 4,
Self::DOUBLE_QUOTED_STRING => 5,
Self::SINGLE_QUOTED_STRING => 6,
Self::VARIABLE => 7,
Self::SEMICOLON => 8,
Self::L_BRACE => 9,
Self::R_BRACE => 10,
Self::RAW_CONTENT => 11,
Self::ERROR => 12,
Self::ROOT => 13,
Self::DIRECTIVE => 14,
Self::BLOCK => 15,
Self::BLANK_LINE => 16,
}
}
}
impl From<SyntaxKind> for rowan::SyntaxKind {
fn from(kind: SyntaxKind) -> Self {
Self(kind.to_raw())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum NginxLanguage {}
impl SyntaxKind {
fn from_raw(raw: u16) -> Self {
match raw {
0 => Self::WHITESPACE,
1 => Self::NEWLINE,
2 => Self::COMMENT,
3 => Self::IDENT,
4 => Self::ARGUMENT,
5 => Self::DOUBLE_QUOTED_STRING,
6 => Self::SINGLE_QUOTED_STRING,
7 => Self::VARIABLE,
8 => Self::SEMICOLON,
9 => Self::L_BRACE,
10 => Self::R_BRACE,
11 => Self::RAW_CONTENT,
12 => Self::ERROR,
13 => Self::ROOT,
14 => Self::DIRECTIVE,
15 => Self::BLOCK,
16 => Self::BLANK_LINE,
_ => panic!("invalid SyntaxKind raw value: {raw}"),
}
}
}
impl rowan::Language for NginxLanguage {
type Kind = SyntaxKind;
fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {
SyntaxKind::from_raw(raw.0)
}
fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind {
kind.into()
}
}
pub type SyntaxNode = rowan::SyntaxNode<NginxLanguage>;
pub type SyntaxToken = rowan::SyntaxToken<NginxLanguage>;
pub type SyntaxElement = rowan::SyntaxElement<NginxLanguage>;
#[cfg(test)]
mod tests {
use super::*;
use rowan::Language;
const ALL_KINDS: &[SyntaxKind] = &[
SyntaxKind::WHITESPACE,
SyntaxKind::NEWLINE,
SyntaxKind::COMMENT,
SyntaxKind::IDENT,
SyntaxKind::ARGUMENT,
SyntaxKind::DOUBLE_QUOTED_STRING,
SyntaxKind::SINGLE_QUOTED_STRING,
SyntaxKind::VARIABLE,
SyntaxKind::SEMICOLON,
SyntaxKind::L_BRACE,
SyntaxKind::R_BRACE,
SyntaxKind::RAW_CONTENT,
SyntaxKind::ERROR,
SyntaxKind::ROOT,
SyntaxKind::DIRECTIVE,
SyntaxKind::BLOCK,
SyntaxKind::BLANK_LINE,
];
#[test]
fn kind_round_trip() {
for (raw, &expected) in ALL_KINDS.iter().enumerate() {
let kind = SyntaxKind::from_raw(raw as u16);
assert_eq!(kind, expected);
let rowan_kind: rowan::SyntaxKind = kind.into();
assert_eq!(rowan_kind.0, raw as u16);
let back = NginxLanguage::kind_from_raw(rowan_kind);
assert_eq!(back, kind);
}
}
#[test]
fn trivia_classification() {
assert!(SyntaxKind::WHITESPACE.is_trivia());
assert!(SyntaxKind::NEWLINE.is_trivia());
assert!(SyntaxKind::COMMENT.is_trivia());
assert!(!SyntaxKind::IDENT.is_trivia());
assert!(!SyntaxKind::SEMICOLON.is_trivia());
}
}