Skip to main content

powdb_query/
token.rs

1#[derive(Debug, Clone, PartialEq)]
2pub enum Token {
3    // Identifiers and literals
4    Ident(String),     // User, name, email
5    DotIdent(String),  // .name, .age (field access)
6    IntLit(i64),       // 42
7    FloatLit(f64),     // 3.14
8    StringLit(String), // "hello"
9    BoolLit(bool),     // true, false
10    Param(String),     // $age, $name (query parameter)
11
12    // Keywords
13    Type,         // type
14    Filter,       // filter
15    Order,        // order
16    Limit,        // limit
17    Offset,       // offset
18    Insert,       // insert
19    Update,       // update
20    Delete,       // delete
21    Upsert,       // upsert
22    Select,       // select (alias for projection)
23    Required,     // required
24    Multi,        // multi
25    Link,         // link
26    Index,        // index
27    Unique,       // unique
28    On,           // on
29    Conflict,     // conflict
30    Asc,          // asc
31    Desc,         // desc
32    And,          // and
33    Or,           // or
34    Not,          // not
35    Exists,       // exists
36    Let,          // let
37    As,           // as
38    Match,        // match
39    Group,        // group
40    Join,         // join
41    Inner,        // inner
42    LeftKw,       // left  (keyword — avoids clashing with ast::JoinKind::LeftOuter naming)
43    RightKw,      // right
44    Outer,        // outer
45    Cross,        // cross
46    Transaction,  // transaction
47    Begin,        // begin
48    Commit,       // commit
49    Rollback,     // rollback
50    View,         // view
51    Materialized, // materialized
52    Refresh,      // refresh
53    Union,        // union
54    Having,       // having
55    Distinct,     // distinct
56    In,           // in
57    Between,      // between
58    Like,         // like
59    Count,        // count
60    Avg,          // avg
61    Sum,          // sum
62    Min,          // min
63    Max,          // max
64    Is,           // is
65    Null,         // null
66
67    // String functions
68    Upper,     // upper
69    Lower,     // lower
70    Length,    // length
71    Trim,      // trim
72    Substring, // substring
73    Concat,    // concat
74
75    // Math functions
76    Abs,   // abs
77    Round, // round
78    Ceil,  // ceil
79    Floor, // floor
80    Sqrt,  // sqrt
81    Pow,   // pow
82
83    // Date/time functions
84    Now,      // now
85    Extract,  // extract
86    DateAdd,  // date_add
87    DateDiff, // date_diff
88
89    // Type conversion
90    Cast, // cast
91
92    // CASE WHEN
93    Case, // case
94    When, // when
95    Then, // then
96    Else, // else
97    End,  // end
98
99    // Window functions
100    Over,      // over
101    Partition, // partition
102    RowNumber, // row_number
103    Rank,      // rank
104    DenseRank, // dense_rank
105
106    // DDL
107    Alter,   // alter
108    Drop,    // drop
109    Add,     // add
110    Column,  // column
111    Explain, // explain
112
113    // Operators
114    Eq,       // =
115    Neq,      // !=
116    Lt,       // <
117    Gt,       // >
118    Lte,      // <=
119    Gte,      // >=
120    Assign,   // :=
121    Arrow,    // ->
122    Pipe,     // |
123    Coalesce, // ??
124    Plus,     // +
125    Minus,    // -
126    Star,     // *
127    Slash,    // /
128
129    // Delimiters
130    LBrace, // {
131    RBrace, // }
132    LParen, // (
133    RParen, // )
134    Comma,  // ,
135    Colon,  // :
136    Dot,    // .
137
138    // Special
139    Eof,
140}
141
142impl Token {
143    /// Human-readable name for error messages. Avoids exposing raw Rust Debug
144    /// format like `IntLit(42)` to end users.
145    pub fn display_name(&self) -> String {
146        match self {
147            // Literals
148            Token::Ident(s) => format!("identifier '{s}'"),
149            Token::DotIdent(s) => format!("field '.{s}'"),
150            Token::IntLit(v) => format!("number {v}"),
151            Token::FloatLit(v) => format!("decimal number {v}"),
152            Token::StringLit(s) => {
153                let preview = if s.len() > 20 {
154                    let end = s.floor_char_boundary(20);
155                    format!("{}...", &s[..end])
156                } else {
157                    s.clone()
158                };
159                format!("string \"{preview}\"")
160            }
161            Token::BoolLit(v) => format!("{v}"),
162            Token::Param(s) => format!("parameter '${s}'"),
163
164            // Keywords
165            Token::Type => "'type'".into(),
166            Token::Filter => "'filter'".into(),
167            Token::Order => "'order'".into(),
168            Token::Limit => "'limit'".into(),
169            Token::Offset => "'offset'".into(),
170            Token::Insert => "'insert'".into(),
171            Token::Update => "'update'".into(),
172            Token::Delete => "'delete'".into(),
173            Token::Upsert => "'upsert'".into(),
174            Token::Select => "'select'".into(),
175            Token::Required => "'required'".into(),
176            Token::Multi => "'multi'".into(),
177            Token::Link => "'link'".into(),
178            Token::Index => "'index'".into(),
179            Token::Unique => "'unique'".into(),
180            Token::On => "'on'".into(),
181            Token::Conflict => "'conflict'".into(),
182            Token::Asc => "'asc'".into(),
183            Token::Desc => "'desc'".into(),
184            Token::And => "'and'".into(),
185            Token::Or => "'or'".into(),
186            Token::Not => "'not'".into(),
187            Token::Exists => "'exists'".into(),
188            Token::Let => "'let'".into(),
189            Token::As => "'as'".into(),
190            Token::Match => "'match'".into(),
191            Token::Group => "'group'".into(),
192            Token::Join => "'join'".into(),
193            Token::Inner => "'inner'".into(),
194            Token::LeftKw => "'left'".into(),
195            Token::RightKw => "'right'".into(),
196            Token::Outer => "'outer'".into(),
197            Token::Cross => "'cross'".into(),
198            Token::Transaction => "'transaction'".into(),
199            Token::Begin => "'begin'".into(),
200            Token::Commit => "'commit'".into(),
201            Token::Rollback => "'rollback'".into(),
202            Token::View => "'view'".into(),
203            Token::Materialized => "'materialized'".into(),
204            Token::Refresh => "'refresh'".into(),
205            Token::Union => "'union'".into(),
206            Token::Having => "'having'".into(),
207            Token::Distinct => "'distinct'".into(),
208            Token::In => "'in'".into(),
209            Token::Between => "'between'".into(),
210            Token::Like => "'like'".into(),
211            Token::Count => "'count'".into(),
212            Token::Avg => "'avg'".into(),
213            Token::Sum => "'sum'".into(),
214            Token::Min => "'min'".into(),
215            Token::Max => "'max'".into(),
216            Token::Is => "'is'".into(),
217            Token::Null => "'null'".into(),
218
219            // Functions
220            Token::Upper => "'upper'".into(),
221            Token::Lower => "'lower'".into(),
222            Token::Length => "'length'".into(),
223            Token::Trim => "'trim'".into(),
224            Token::Substring => "'substring'".into(),
225            Token::Concat => "'concat'".into(),
226            Token::Abs => "'abs'".into(),
227            Token::Round => "'round'".into(),
228            Token::Ceil => "'ceil'".into(),
229            Token::Floor => "'floor'".into(),
230            Token::Sqrt => "'sqrt'".into(),
231            Token::Pow => "'pow'".into(),
232            Token::Now => "'now'".into(),
233            Token::Extract => "'extract'".into(),
234            Token::DateAdd => "'date_add'".into(),
235            Token::DateDiff => "'date_diff'".into(),
236            Token::Cast => "'cast'".into(),
237            Token::Case => "'case'".into(),
238            Token::When => "'when'".into(),
239            Token::Then => "'then'".into(),
240            Token::Else => "'else'".into(),
241            Token::End => "'end'".into(),
242
243            // Window
244            Token::Over => "'over'".into(),
245            Token::Partition => "'partition'".into(),
246            Token::RowNumber => "'row_number'".into(),
247            Token::Rank => "'rank'".into(),
248            Token::DenseRank => "'dense_rank'".into(),
249
250            // DDL
251            Token::Alter => "'alter'".into(),
252            Token::Drop => "'drop'".into(),
253            Token::Add => "'add'".into(),
254            Token::Column => "'column'".into(),
255            Token::Explain => "'explain'".into(),
256
257            // Operators
258            Token::Eq => "'='".into(),
259            Token::Neq => "'!='".into(),
260            Token::Lt => "'<'".into(),
261            Token::Gt => "'>'".into(),
262            Token::Lte => "'<='".into(),
263            Token::Gte => "'>='".into(),
264            Token::Assign => "':='".into(),
265            Token::Arrow => "'->'".into(),
266            Token::Pipe => "'|'".into(),
267            Token::Coalesce => "'??'".into(),
268            Token::Plus => "'+'".into(),
269            Token::Minus => "'-'".into(),
270            Token::Star => "'*'".into(),
271            Token::Slash => "'/'".into(),
272
273            // Delimiters
274            Token::LBrace => "'{'".into(),
275            Token::RBrace => "'}'".into(),
276            Token::LParen => "'('".into(),
277            Token::RParen => "')'".into(),
278            Token::Comma => "','".into(),
279            Token::Colon => "':'".into(),
280            Token::Dot => "'.'".into(),
281
282            Token::Eof => "end of input".into(),
283        }
284    }
285}