1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15pub enum CommonKeyword {
16 Match,
19 Return,
21 Where,
23 As,
25 Distinct,
27 With,
29 Optional,
31
32 Order,
35 By,
37 Asc,
39 Desc,
41 Limit,
43 Skip,
45
46 And,
49 Or,
51 Not,
53
54 In,
57 Is,
59 Like,
61
62 Starts,
65 Ends,
67 Contains,
69
70 Null,
73 True,
75 False,
77
78 Create,
81 Delete,
83 Set,
85 Remove,
87 Merge,
89 Detach,
91 On,
93
94 Call,
97 Yield,
99 Exists,
101 Unwind,
103
104 Node,
107 Edge,
109
110 Having,
113 Case,
115 When,
117 Then,
119 Else,
121 End,
123}
124
125impl CommonKeyword {
126 #[must_use]
131 pub fn from_uppercase(text: &str) -> Option<Self> {
132 match text {
133 "MATCH" => Some(Self::Match),
135 "RETURN" => Some(Self::Return),
136 "WHERE" => Some(Self::Where),
137 "AS" => Some(Self::As),
138 "DISTINCT" => Some(Self::Distinct),
139 "WITH" => Some(Self::With),
140 "OPTIONAL" => Some(Self::Optional),
141
142 "ORDER" => Some(Self::Order),
144 "BY" => Some(Self::By),
145 "ASC" => Some(Self::Asc),
146 "DESC" => Some(Self::Desc),
147 "LIMIT" => Some(Self::Limit),
148 "SKIP" => Some(Self::Skip),
149
150 "AND" => Some(Self::And),
152 "OR" => Some(Self::Or),
153 "NOT" => Some(Self::Not),
154
155 "IN" => Some(Self::In),
157 "IS" => Some(Self::Is),
158 "LIKE" => Some(Self::Like),
159
160 "STARTS" => Some(Self::Starts),
162 "ENDS" => Some(Self::Ends),
163 "CONTAINS" => Some(Self::Contains),
164
165 "NULL" => Some(Self::Null),
167 "TRUE" => Some(Self::True),
168 "FALSE" => Some(Self::False),
169
170 "CREATE" => Some(Self::Create),
172 "DELETE" => Some(Self::Delete),
173 "SET" => Some(Self::Set),
174 "REMOVE" => Some(Self::Remove),
175 "MERGE" => Some(Self::Merge),
176 "DETACH" => Some(Self::Detach),
177 "ON" => Some(Self::On),
178
179 "CALL" => Some(Self::Call),
181 "YIELD" => Some(Self::Yield),
182 "EXISTS" => Some(Self::Exists),
183 "UNWIND" => Some(Self::Unwind),
184
185 "NODE" => Some(Self::Node),
187 "EDGE" => Some(Self::Edge),
188
189 "HAVING" => Some(Self::Having),
191 "CASE" => Some(Self::Case),
192 "WHEN" => Some(Self::When),
193 "THEN" => Some(Self::Then),
194 "ELSE" => Some(Self::Else),
195 "END" => Some(Self::End),
196
197 _ => None,
198 }
199 }
200
201 #[must_use]
203 pub fn is_keyword(text: &str) -> bool {
204 Self::from_uppercase(text).is_some()
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use super::*;
211
212 #[test]
213 fn test_common_keywords_recognized() {
214 assert_eq!(
216 CommonKeyword::from_uppercase("MATCH"),
217 Some(CommonKeyword::Match)
218 );
219 assert_eq!(
220 CommonKeyword::from_uppercase("RETURN"),
221 Some(CommonKeyword::Return)
222 );
223 assert_eq!(
224 CommonKeyword::from_uppercase("WHERE"),
225 Some(CommonKeyword::Where)
226 );
227
228 assert_eq!(
230 CommonKeyword::from_uppercase("AND"),
231 Some(CommonKeyword::And)
232 );
233 assert_eq!(CommonKeyword::from_uppercase("OR"), Some(CommonKeyword::Or));
234 assert_eq!(
235 CommonKeyword::from_uppercase("NOT"),
236 Some(CommonKeyword::Not)
237 );
238
239 assert_eq!(
241 CommonKeyword::from_uppercase("NULL"),
242 Some(CommonKeyword::Null)
243 );
244 assert_eq!(
245 CommonKeyword::from_uppercase("TRUE"),
246 Some(CommonKeyword::True)
247 );
248 assert_eq!(
249 CommonKeyword::from_uppercase("FALSE"),
250 Some(CommonKeyword::False)
251 );
252 }
253
254 #[test]
255 fn test_non_keywords_return_none() {
256 assert_eq!(CommonKeyword::from_uppercase("FOOBAR"), None);
257 assert_eq!(CommonKeyword::from_uppercase("person"), None);
258 assert_eq!(CommonKeyword::from_uppercase(""), None);
259 }
260
261 #[test]
262 fn test_is_keyword() {
263 assert!(CommonKeyword::is_keyword("MATCH"));
264 assert!(CommonKeyword::is_keyword("WHERE"));
265 assert!(!CommonKeyword::is_keyword("FOOBAR"));
266 }
267
268 #[test]
269 fn test_language_specific_not_common() {
270 assert_eq!(CommonKeyword::from_uppercase("SELECT"), None);
272 assert_eq!(CommonKeyword::from_uppercase("FROM"), None);
273 assert_eq!(CommonKeyword::from_uppercase("GRAPH_TABLE"), None);
274
275 assert_eq!(CommonKeyword::from_uppercase("UNION"), None);
277 assert_eq!(CommonKeyword::from_uppercase("XOR"), None);
278
279 assert_eq!(CommonKeyword::from_uppercase("VECTOR"), None);
281 assert_eq!(CommonKeyword::from_uppercase("INDEX"), None);
282 }
283
284 #[test]
285 fn test_all_common_keywords_covered() {
286 let all_keywords = [
287 "MATCH", "RETURN", "WHERE", "AS", "DISTINCT", "WITH", "OPTIONAL", "ORDER", "BY", "ASC",
288 "DESC", "LIMIT", "SKIP", "AND", "OR", "NOT", "IN", "IS", "LIKE", "STARTS", "ENDS",
289 "CONTAINS", "NULL", "TRUE", "FALSE", "CREATE", "DELETE", "SET", "REMOVE", "MERGE",
290 "DETACH", "ON", "CALL", "YIELD", "EXISTS", "UNWIND", "NODE", "EDGE", "HAVING", "CASE",
291 "WHEN", "THEN", "ELSE", "END",
292 ];
293
294 for kw in &all_keywords {
295 assert!(
296 CommonKeyword::from_uppercase(kw).is_some(),
297 "Expected '{kw}' to be recognized as a common keyword"
298 );
299 }
300 }
301}