arity_parser/rd/
syntax.rs1macro_rules! syntax_kinds {
4 ($($kind:ident),+ $(,)?) => {
5 #[allow(non_camel_case_types)]
7 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
8 serde::Serialize, serde::Deserialize)]
9 #[repr(u16)]
10 pub enum SyntaxKind { $($kind),+ }
11
12 impl SyntaxKind {
13 pub const ALL: &'static [Self] = &[$(Self::$kind),+];
15 }
16 };
17}
18
19syntax_kinds! {
20 ROOT, MACRO, ARGUMENT, GROUP, OPTION, CONDITIONAL,
21 MACRO_NAME, LBRACE, RBRACE, LBRACKET, RBRACKET,
22 TEXT, RCODE, VERBATIM, ESCAPED_TEXT, ESCAPED_RCODE, ESCAPED_VERBATIM, R_STRING_ESCAPE,
23 COMMENT, DIRECTIVE, TARGET, ERROR,
24}
25
26impl From<SyntaxKind> for rowan::SyntaxKind {
27 fn from(kind: SyntaxKind) -> Self {
28 Self(kind as u16)
29 }
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
34pub enum RdLanguage {}
35
36impl rowan::Language for RdLanguage {
37 type Kind = SyntaxKind;
38
39 fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {
40 SyntaxKind::ALL
41 .get(usize::from(raw.0))
42 .copied()
43 .unwrap_or(SyntaxKind::ERROR)
44 }
45
46 fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind {
47 kind.into()
48 }
49}
50
51pub type SyntaxNode = rowan::SyntaxNode<RdLanguage>;
52pub type SyntaxToken = rowan::SyntaxToken<RdLanguage>;
53pub type SyntaxElement = rowan::SyntaxElement<RdLanguage>;
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use rowan::Language;
59
60 #[test]
61 fn kinds_round_trip() {
62 for &kind in SyntaxKind::ALL {
63 assert_eq!(
64 RdLanguage::kind_from_raw(RdLanguage::kind_to_raw(kind)),
65 kind
66 );
67 }
68 assert_eq!(
69 RdLanguage::kind_from_raw(rowan::SyntaxKind(u16::MAX)),
70 SyntaxKind::ERROR
71 );
72 }
73}