1use crate::common::eof;
2use nom::{
3 branch::alt,
4 bytes::complete::{tag, tag_no_case},
5 combinator::{map, peek},
6 sequence::terminated,
7 IResult,
8};
9
10#[derive(Debug, PartialEq)]
12pub enum ReservedKeyword {
13 Add,
14 Aggregate,
15 Allow,
16 Alter,
17 And,
18 Any,
19 Apply,
20 Asc,
21 Authorize,
22 Batch,
23 Begin,
24 By,
25 ColumnFamily,
26 Create,
27 Delete,
28 Desc,
29 Drop,
30 EachQuorum,
31 Entries,
32 From,
33 Full,
34 Grant,
35 If,
36 In,
37 Index,
38 Inet,
39 Infinity,
40 Insert,
41 Into,
42 Keyspace,
43 Keyspaces,
44 Limit,
45 LocalOne,
46 LocalQuorum,
47 Materialized,
48 Modify,
49 Nan,
50 NoRecursive,
51 Not,
52 Of,
53 On,
54 One,
55 Order,
56 Partition,
57 Password,
58 Per,
59 Primary,
60 Quorum,
61 Rename,
62 Revoke,
63 Schema,
64 Select,
65 Set,
66 Table,
67 Time,
68 Three,
69 To,
70 Token,
71 Truncate,
72 Two,
73 Unlogged,
74 Update,
75 Use,
76 Using,
77 Values,
78 View,
79 Where,
80 With,
81 WriteTime,
82}
83
84macro_rules! impl_keyword_parser {
85 ($keyword:literal, $enum_member:ident) => {
86 map(
87 terminated(tag_no_case($keyword), keyword_follow_char),
88 |_| ReservedKeyword::$enum_member,
89 )
90 };
91}
92
93fn keywords_alpha(input: &str) -> IResult<&str, ReservedKeyword> {
94 alt((
95 impl_keyword_parser!("ADD", Add),
96 impl_keyword_parser!("AGGREGATE", Aggregate),
97 impl_keyword_parser!("ALLOW", Allow),
98 impl_keyword_parser!("ALTER", Alter),
99 impl_keyword_parser!("AND", And),
100 impl_keyword_parser!("ANY", Any),
101 impl_keyword_parser!("APPLY", Apply),
102 impl_keyword_parser!("ASC", Asc),
103 impl_keyword_parser!("AUTHORIZE", Authorize),
104 impl_keyword_parser!("BATCH", Batch),
105 impl_keyword_parser!("BEGIN", Begin),
106 impl_keyword_parser!("BY", By),
107 impl_keyword_parser!("COLUMNFAMILY", ColumnFamily),
108 impl_keyword_parser!("CREATE", Create),
109 impl_keyword_parser!("DELETE", Delete),
110 impl_keyword_parser!("DESC", Desc),
111 impl_keyword_parser!("DROP", Drop),
112 impl_keyword_parser!("EACH_QUORUM", EachQuorum),
113 impl_keyword_parser!("ENTRIES", Entries),
114 impl_keyword_parser!("FROM", From),
115 ))(input)
116}
117
118fn keywords_bravo(input: &str) -> IResult<&str, ReservedKeyword> {
119 alt((
120 impl_keyword_parser!("FULL", Full),
121 impl_keyword_parser!("GRANT", Grant),
122 impl_keyword_parser!("IF", If),
123 impl_keyword_parser!("IN", In),
124 impl_keyword_parser!("INDEX", Index),
125 impl_keyword_parser!("INET", Inet),
126 impl_keyword_parser!("INFINITY", Infinity),
127 impl_keyword_parser!("INSERT", Insert),
128 impl_keyword_parser!("INTO", Into),
129 impl_keyword_parser!("KEYSPACE", Keyspace),
130 impl_keyword_parser!("KEYSPACES", Keyspaces),
131 impl_keyword_parser!("LIMIT", Limit),
132 impl_keyword_parser!("LOCAL_ONE", LocalOne),
133 impl_keyword_parser!("LOCAL_QUORUM", LocalQuorum),
134 impl_keyword_parser!("MATERIALIZED", Materialized),
135 impl_keyword_parser!("MODIFY", Modify),
136 impl_keyword_parser!("NAN", Nan),
137 impl_keyword_parser!("NORECURSIVE", NoRecursive),
138 impl_keyword_parser!("NOT", Not),
139 impl_keyword_parser!("OF", Of),
140 impl_keyword_parser!("ON", On),
141 ))(input)
142}
143
144fn keywords_charlie(input: &str) -> IResult<&str, ReservedKeyword> {
145 alt((
146 impl_keyword_parser!("ONE", One),
147 impl_keyword_parser!("ORDER", Order),
148 impl_keyword_parser!("PARTITION", Partition),
149 impl_keyword_parser!("PASSWORD", Password),
150 impl_keyword_parser!("PER", Per),
151 impl_keyword_parser!("PRIMARY", Primary),
152 impl_keyword_parser!("QUORUM", Quorum),
153 impl_keyword_parser!("RENAME", Rename),
154 impl_keyword_parser!("REVOKE", Revoke),
155 impl_keyword_parser!("SCHEMA", Schema),
156 impl_keyword_parser!("SELECT", Select),
157 impl_keyword_parser!("SET", Set),
158 impl_keyword_parser!("TABLE", Table),
159 impl_keyword_parser!("TIME", Time),
160 impl_keyword_parser!("THREE", Three),
161 impl_keyword_parser!("TO", To),
162 impl_keyword_parser!("TOKEN", Token),
163 impl_keyword_parser!("TRUNCATE", Truncate),
164 impl_keyword_parser!("TWO", Two),
165 impl_keyword_parser!("UNLOGGED", Unlogged),
166 impl_keyword_parser!("UPDATE", Update),
167 ))(input)
168}
169
170fn keywords_delta(input: &str) -> IResult<&str, ReservedKeyword> {
171 alt((
172 impl_keyword_parser!("USE", Use),
173 impl_keyword_parser!("USING", Using),
174 impl_keyword_parser!("VALUES", Values),
175 impl_keyword_parser!("VIEW", View),
176 impl_keyword_parser!("WHERE", Where),
177 impl_keyword_parser!("WITH", With),
178 ))(input)
179}
180
181pub fn parse_cql_keyword(input: &str) -> IResult<&str, ReservedKeyword> {
183 alt((
184 keywords_alpha,
185 keywords_bravo,
186 keywords_charlie,
187 keywords_delta,
188 ))(input)
189}
190
191pub fn fail_if_keyword(input: &str) -> IResult<&str, ReservedKeyword> {
194 alt((
197 keywords_alpha,
198 keywords_bravo,
199 keywords_charlie,
200 keywords_delta,
201 ))(input)
202}
203
204fn keyword_follow_char(i: &str) -> IResult<&str, &str> {
205 peek(alt((
206 tag(" "),
207 tag("\n"),
208 tag(";"),
209 tag("("),
210 tag(")"),
211 tag("\t"),
212 tag(","),
213 tag("="),
214 eof,
215 )))(i)
216}
217
218#[cfg(test)]
219mod test {
220 use super::*;
221
222 #[test]
223 fn test_parse_cql_keyword() {
224 assert_eq!(parse_cql_keyword("ADD"), Ok(("", ReservedKeyword::Add)));
225 assert_eq!(parse_cql_keyword("ADD "), Ok((" ", ReservedKeyword::Add)));
226 assert_eq!(parse_cql_keyword("ADD;"), Ok((";", ReservedKeyword::Add)));
227 assert_eq!(parse_cql_keyword("ADD\n"), Ok(("\n", ReservedKeyword::Add)));
228 assert_eq!(parse_cql_keyword("ADD("), Ok(("(", ReservedKeyword::Add)));
229 assert_eq!(parse_cql_keyword("ADD)"), Ok((")", ReservedKeyword::Add)));
230 assert_eq!(parse_cql_keyword("ADD\t"), Ok(("\t", ReservedKeyword::Add)));
231 assert_eq!(parse_cql_keyword("ADD,"), Ok((",", ReservedKeyword::Add)));
232 assert_eq!(parse_cql_keyword("ADD="), Ok(("=", ReservedKeyword::Add)));
233 }
234
235 #[test]
236 fn test_fail_parse_cql_keyword() {
237 assert!(parse_cql_keyword("my_variable").is_err());
238 }
239}