oak_django/lexer/token_type.rs
1use oak_core::{Token, TokenType, UniversalTokenRole};
2
3/// Django token type alias.
4pub type DjangoToken = Token<DjangoTokenType>;
5
6/// Token types for the Django template lexer.
7///
8/// This enum represents all possible token types in Django templates,
9/// including template tags, variables, filters, and HTML content.
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub enum DjangoTokenType {
13 // Basic tokens
14 /// Identifier token.
15 Identifier,
16 /// Number literal token.
17 Number,
18 /// String literal token.
19 String,
20 /// Whitespace token.
21 Whitespace,
22 /// Newline token.
23 Newline,
24 /// Comment token.
25 Comment,
26
27 // Django template delimiters
28 /// Variable start delimiter `{{`.
29 VariableStart,
30 /// Variable end delimiter `}}`.
31 VariableEnd,
32 /// Tag start delimiter `{%`.
33 TagStart,
34 /// Tag end delimiter `%}`.
35 TagEnd,
36 /// Comment start delimiter `{#`.
37 CommentStart,
38 /// Comment end delimiter `#}`.
39 CommentEnd,
40
41 // Django tag keywords
42 /// `if` keyword for conditional blocks.
43 If,
44 /// `elif` keyword for else-if branches.
45 Elif,
46 /// `else` keyword for else branches.
47 Else,
48 /// `endif` keyword to close if blocks.
49 Endif,
50 /// `for` keyword for loop blocks.
51 For,
52 /// `empty` keyword for empty loop fallback.
53 Empty,
54 /// `endfor` keyword to close for loops.
55 Endfor,
56 /// `block` keyword for template inheritance.
57 Block,
58 /// `endblock` keyword to close block sections.
59 Endblock,
60 /// `extends` keyword for template inheritance.
61 Extends,
62 /// `include` keyword for including other templates.
63 Include,
64 /// `load` keyword for loading template tags.
65 Load,
66 /// `with` keyword for context variables.
67 With,
68 /// `endwith` keyword to close with blocks.
69 Endwith,
70 /// `autoescape` keyword for auto-escaping.
71 Autoescape,
72 /// `endautoescape` keyword to close autoescape blocks.
73 Endautoescape,
74 /// `csrf_token` tag for CSRF protection.
75 Csrf,
76 /// `url` tag for URL resolution.
77 Url,
78 /// `static` tag for static file references.
79 Static,
80 /// `now` tag for current datetime.
81 Now,
82 /// `cycle` tag for cycling values.
83 Cycle,
84 /// `filter` tag for filter sections.
85 Filter,
86 /// `endfilter` keyword to close filter blocks.
87 Endfilter,
88 /// `spaceless` tag for removing whitespace.
89 Spaceless,
90 /// `endspaceless` keyword to close spaceless blocks.
91 Endspaceless,
92 /// `verbatim` tag for literal content.
93 Verbatim,
94 /// `endverbatim` keyword to close verbatim blocks.
95 Endverbatim,
96 /// `and` logical operator.
97 And,
98 /// `or` logical operator.
99 Or,
100 /// `not` logical operator.
101 Not,
102 /// `in` membership operator.
103 In,
104
105 // Symbols
106 /// Dot operator `.`.
107 Dot,
108 /// Pipe operator `|` for filters.
109 Pipe,
110 /// Colon `:`.
111 Colon,
112 /// Comma `,`.
113 Comma,
114 /// Assignment operator `=`.
115 Equal,
116 /// Equality operator `==`.
117 EqualEqual,
118 /// Inequality operator `!=`.
119 NotEqual,
120 /// Less than operator `<`.
121 Less,
122 /// Greater than operator `>`.
123 Greater,
124 /// Less than or equal operator `<=`.
125 LessEqual,
126 /// Greater than or equal operator `>=`.
127 GreaterEqual,
128 /// Plus operator `+`.
129 Plus,
130 /// Minus operator `-`.
131 Minus,
132 /// Multiplication operator `*`.
133 Star,
134 /// Division operator `/`.
135 Slash,
136 /// Modulo operator `%`.
137 Percent,
138
139 // Brackets
140 /// Left parenthesis `(`.
141 LeftParen,
142 /// Right parenthesis `)`.
143 RightParen,
144 /// Left bracket `[`.
145 LeftBracket,
146 /// Right bracket `]`.
147 RightBracket,
148 /// Semicolon `;`.
149 Semicolon,
150
151 // Special tokens
152 /// HTML content outside Django tags.
153 HtmlContent,
154 /// End of file token.
155 Eof,
156 /// Error token for invalid input.
157 Error,
158}
159
160impl DjangoTokenType {
161 /// Returns `true` if this token is a Django keyword.
162 pub fn is_keyword(&self) -> bool {
163 matches!(
164 self,
165 Self::If
166 | Self::Elif
167 | Self::Else
168 | Self::Endif
169 | Self::For
170 | Self::Empty
171 | Self::Endfor
172 | Self::Block
173 | Self::Endblock
174 | Self::Extends
175 | Self::Include
176 | Self::Load
177 | Self::With
178 | Self::Endwith
179 | Self::Autoescape
180 | Self::Endautoescape
181 | Self::Csrf
182 | Self::Url
183 | Self::Static
184 | Self::Now
185 | Self::Cycle
186 | Self::Filter
187 | Self::Endfilter
188 | Self::Spaceless
189 | Self::Endspaceless
190 | Self::Verbatim
191 | Self::Endverbatim
192 | Self::And
193 | Self::Or
194 | Self::Not
195 | Self::In
196 )
197 }
198
199 /// Returns true if this token type is trivia (whitespace, newline, or comment).
200 pub fn is_trivia(&self) -> bool {
201 matches!(self, Self::Whitespace | Self::Newline | Self::Comment)
202 }
203}
204
205impl TokenType for DjangoTokenType {
206 type Role = UniversalTokenRole;
207 const END_OF_STREAM: Self = Self::Eof;
208
209 fn is_ignored(&self) -> bool {
210 self.is_trivia()
211 }
212
213 fn role(&self) -> Self::Role {
214 match self {
215 Self::If
216 | Self::Elif
217 | Self::Else
218 | Self::Endif
219 | Self::For
220 | Self::Empty
221 | Self::Endfor
222 | Self::Block
223 | Self::Endblock
224 | Self::Extends
225 | Self::Include
226 | Self::Load
227 | Self::With
228 | Self::Endwith
229 | Self::Autoescape
230 | Self::Endautoescape
231 | Self::Csrf
232 | Self::Url
233 | Self::Static
234 | Self::Now
235 | Self::Cycle
236 | Self::Filter
237 | Self::Endfilter
238 | Self::Spaceless
239 | Self::Endspaceless
240 | Self::Verbatim
241 | Self::Endverbatim
242 | Self::And
243 | Self::Or
244 | Self::Not
245 | Self::In => UniversalTokenRole::Keyword,
246
247 Self::Dot
248 | Self::Pipe
249 | Self::Colon
250 | Self::Comma
251 | Self::Equal
252 | Self::NotEqual
253 | Self::Less
254 | Self::Greater
255 | Self::LessEqual
256 | Self::GreaterEqual
257 | Self::Plus
258 | Self::Minus
259 | Self::Star
260 | Self::Slash
261 | Self::Percent
262 | Self::LeftParen
263 | Self::RightParen
264 | Self::LeftBracket
265 | Self::RightBracket
266 | Self::Semicolon => UniversalTokenRole::Punctuation,
267
268 Self::Identifier => UniversalTokenRole::Name,
269 Self::Number | Self::String => UniversalTokenRole::Literal,
270
271 Self::Whitespace | Self::Newline => UniversalTokenRole::Whitespace,
272 Self::Comment => UniversalTokenRole::Comment,
273 Self::Error => UniversalTokenRole::Error,
274 _ => UniversalTokenRole::None,
275 }
276 }
277}