Skip to main content

oak_django/kind/
mod.rs

1use oak_core::{Token, TokenType, UniversalTokenRole};
2use serde::{Deserialize, Serialize};
3
4pub type DjangoToken = Token<DjangoSyntaxKind>;
5
6/// Django 模板语法种类
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8pub enum DjangoSyntaxKind {
9    // 基本 kind
10    Identifier,
11    Number,
12    String,
13    Whitespace,
14    Newline,
15
16    // Django 模板标签
17    VariableStart, // {{
18    VariableEnd,   // }}
19    TagStart,      // {%
20    TagEnd,        // %}
21    CommentStart,  // {#
22    CommentEnd,    // #}
23
24    // Django 标签关键字
25    If,
26    Elif,
27    Else,
28    Endif,
29    For,
30    Empty,
31    Endfor,
32    Block,
33    Endblock,
34    Extends,
35    Include,
36    Load,
37    With,
38    Endwith,
39    Autoescape,
40    Endautoescape,
41    Csrf,
42    Url,
43    Static,
44    Now,
45    Cycle,
46    Filter,
47    Endfilter,
48    Spaceless,
49    Endspaceless,
50    Verbatim,
51    Endverbatim,
52
53    // 过滤器和操作符
54    Pipe,    // |
55    Colon,   // :
56    Dot,     // .
57    Comma,   // ,
58    Equal,   // =
59    Plus,    // +
60    Minus,   // -
61    Star,    // *
62    Slash,   // /
63    Percent, // %
64
65    // 比较操作符
66    EqualEqual,   // ==
67    NotEqual,     // !=
68    Less,         // <
69    LessEqual,    // <=
70    Greater,      // >
71    GreaterEqual, // >=
72
73    // 逻辑操作符
74    And,
75    Or,
76    Not,
77    In,
78
79    // 括号
80    LeftParen,    // (
81    RightParen,   // )
82    LeftBracket,  // [
83    RightBracket, // ]
84    Semicolon,    // ;
85
86    // HTML 内容
87    HtmlText,
88    HtmlTag,
89
90    // 注释
91    Comment,
92
93    // 节点类型
94    Variable,
95    Tag,
96
97    // 特殊
98    Root,
99    Error,
100    Eof,
101}
102
103impl DjangoSyntaxKind {
104    pub fn is_keyword(&self) -> bool {
105        matches!(
106            self,
107            Self::If
108                | Self::Elif
109                | Self::Else
110                | Self::Endif
111                | Self::For
112                | Self::Empty
113                | Self::Endfor
114                | Self::Block
115                | Self::Endblock
116                | Self::Extends
117                | Self::Include
118                | Self::Load
119                | Self::With
120                | Self::Endwith
121                | Self::Autoescape
122                | Self::Endautoescape
123                | Self::Csrf
124                | Self::Url
125                | Self::Static
126                | Self::Now
127                | Self::Cycle
128                | Self::Filter
129                | Self::Endfilter
130                | Self::Spaceless
131                | Self::Endspaceless
132                | Self::Verbatim
133                | Self::Endverbatim
134                | Self::And
135                | Self::Or
136                | Self::Not
137                | Self::In
138        )
139    }
140
141    pub fn is_trivia(&self) -> bool {
142        matches!(self, Self::Whitespace | Self::Newline | Self::Comment)
143    }
144}
145
146impl TokenType for DjangoSyntaxKind {
147    type Role = UniversalTokenRole;
148    const END_OF_STREAM: Self = Self::Eof;
149
150    fn role(&self) -> Self::Role {
151        if self.is_keyword() {
152            return UniversalTokenRole::Keyword;
153        }
154
155        match self {
156            Self::Identifier => UniversalTokenRole::Name,
157            Self::Number | Self::String => UniversalTokenRole::Literal,
158            Self::Whitespace | Self::Newline => UniversalTokenRole::Whitespace,
159            Self::Comment => UniversalTokenRole::Comment,
160            Self::VariableStart | Self::VariableEnd | Self::TagStart | Self::TagEnd | Self::CommentStart | Self::CommentEnd => UniversalTokenRole::Punctuation,
161            Self::Pipe | Self::Colon | Self::Dot | Self::Comma | Self::Equal | Self::Plus | Self::Minus | Self::Star | Self::Slash | Self::Percent | Self::EqualEqual | Self::NotEqual | Self::Less | Self::LessEqual | Self::Greater | Self::GreaterEqual => {
162                UniversalTokenRole::Operator
163            }
164            Self::LeftParen | Self::RightParen | Self::LeftBracket | Self::RightBracket | Self::Semicolon => UniversalTokenRole::Punctuation,
165            Self::HtmlText | Self::HtmlTag => UniversalTokenRole::None,
166            Self::Error => UniversalTokenRole::Error,
167            _ => UniversalTokenRole::None,
168        }
169    }
170
171    fn is_ignored(&self) -> bool {
172        matches!(self, Self::Whitespace | Self::Newline | Self::Comment)
173    }
174
175    fn is_comment(&self) -> bool {
176        matches!(self, Self::Comment)
177    }
178
179    fn is_whitespace(&self) -> bool {
180        matches!(self, Self::Whitespace | Self::Newline)
181    }
182}
183
184impl oak_core::ElementType for DjangoSyntaxKind {
185    type Role = oak_core::UniversalElementRole;
186
187    fn role(&self) -> Self::Role {
188        match self {
189            Self::Root => oak_core::UniversalElementRole::Root,
190            Self::Variable | Self::Tag => oak_core::UniversalElementRole::Statement,
191            Self::Error => oak_core::UniversalElementRole::Error,
192            _ => oak_core::UniversalElementRole::None,
193        }
194    }
195
196    fn is_error(&self) -> bool {
197        matches!(self, Self::Error)
198    }
199}