#[derive(Debug, Clone, PartialEq)]
pub enum Token {
Ident(String), DotIdent(String), IntLit(i64), FloatLit(f64), StringLit(String), BoolLit(bool), Param(String),
Type, Filter, Order, Limit, Offset, Insert, Update, Delete, Upsert, Returning, Select, Required, Default, Auto, Multi, Link, Index, Unique, On, Conflict, Asc, Desc, And, Or, Not, Exists, Let, As, Match, Group, Join, Inner, LeftKw, RightKw, Outer, Cross, Transaction, Begin, Commit, Rollback, View, Materialized, Refresh, Union, Having, Distinct, In, Between, Like, Count, Avg, Sum, Min, Max, Is, Null,
Upper, Lower, Length, Trim, Substring, Concat,
Abs, Round, Ceil, Floor, Sqrt, Pow,
Now, Extract, DateAdd, DateDiff,
Cast,
Case, When, Then, Else, End,
Over, Partition, RowNumber, Rank, DenseRank,
Alter, Drop, Add, Column, Explain, Schema, Describe,
Eq, Neq, Lt, Gt, Lte, Gte, Assign, Arrow, Pipe, Coalesce, Plus, Minus, Star, Slash,
LBrace, RBrace, LParen, RParen, Comma, Colon, Dot,
Eof,
}
impl Token {
pub fn display_name(&self) -> String {
match self {
Token::Ident(s) => format!("identifier '{s}'"),
Token::DotIdent(s) => format!("field '.{s}'"),
Token::IntLit(v) => format!("number {v}"),
Token::FloatLit(v) => format!("decimal number {v}"),
Token::StringLit(s) => {
let preview = if s.len() > 20 {
let end = s.floor_char_boundary(20);
format!("{}...", &s[..end])
} else {
s.clone()
};
format!("string \"{preview}\"")
}
Token::BoolLit(v) => format!("{v}"),
Token::Param(s) => format!("parameter '${s}'"),
Token::Type => "'type'".into(),
Token::Filter => "'filter'".into(),
Token::Order => "'order'".into(),
Token::Limit => "'limit'".into(),
Token::Offset => "'offset'".into(),
Token::Insert => "'insert'".into(),
Token::Update => "'update'".into(),
Token::Delete => "'delete'".into(),
Token::Upsert => "'upsert'".into(),
Token::Returning => "'returning'".into(),
Token::Select => "'select'".into(),
Token::Required => "'required'".into(),
Token::Default => "'default'".into(),
Token::Auto => "'auto'".into(),
Token::Multi => "'multi'".into(),
Token::Link => "'link'".into(),
Token::Index => "'index'".into(),
Token::Unique => "'unique'".into(),
Token::On => "'on'".into(),
Token::Conflict => "'conflict'".into(),
Token::Asc => "'asc'".into(),
Token::Desc => "'desc'".into(),
Token::And => "'and'".into(),
Token::Or => "'or'".into(),
Token::Not => "'not'".into(),
Token::Exists => "'exists'".into(),
Token::Let => "'let'".into(),
Token::As => "'as'".into(),
Token::Match => "'match'".into(),
Token::Group => "'group'".into(),
Token::Join => "'join'".into(),
Token::Inner => "'inner'".into(),
Token::LeftKw => "'left'".into(),
Token::RightKw => "'right'".into(),
Token::Outer => "'outer'".into(),
Token::Cross => "'cross'".into(),
Token::Transaction => "'transaction'".into(),
Token::Begin => "'begin'".into(),
Token::Commit => "'commit'".into(),
Token::Rollback => "'rollback'".into(),
Token::View => "'view'".into(),
Token::Materialized => "'materialized'".into(),
Token::Refresh => "'refresh'".into(),
Token::Union => "'union'".into(),
Token::Having => "'having'".into(),
Token::Distinct => "'distinct'".into(),
Token::In => "'in'".into(),
Token::Between => "'between'".into(),
Token::Like => "'like'".into(),
Token::Count => "'count'".into(),
Token::Avg => "'avg'".into(),
Token::Sum => "'sum'".into(),
Token::Min => "'min'".into(),
Token::Max => "'max'".into(),
Token::Is => "'is'".into(),
Token::Null => "'null'".into(),
Token::Upper => "'upper'".into(),
Token::Lower => "'lower'".into(),
Token::Length => "'length'".into(),
Token::Trim => "'trim'".into(),
Token::Substring => "'substring'".into(),
Token::Concat => "'concat'".into(),
Token::Abs => "'abs'".into(),
Token::Round => "'round'".into(),
Token::Ceil => "'ceil'".into(),
Token::Floor => "'floor'".into(),
Token::Sqrt => "'sqrt'".into(),
Token::Pow => "'pow'".into(),
Token::Now => "'now'".into(),
Token::Extract => "'extract'".into(),
Token::DateAdd => "'date_add'".into(),
Token::DateDiff => "'date_diff'".into(),
Token::Cast => "'cast'".into(),
Token::Case => "'case'".into(),
Token::When => "'when'".into(),
Token::Then => "'then'".into(),
Token::Else => "'else'".into(),
Token::End => "'end'".into(),
Token::Over => "'over'".into(),
Token::Partition => "'partition'".into(),
Token::RowNumber => "'row_number'".into(),
Token::Rank => "'rank'".into(),
Token::DenseRank => "'dense_rank'".into(),
Token::Alter => "'alter'".into(),
Token::Drop => "'drop'".into(),
Token::Add => "'add'".into(),
Token::Column => "'column'".into(),
Token::Explain => "'explain'".into(),
Token::Schema => "'schema'".into(),
Token::Describe => "'describe'".into(),
Token::Eq => "'='".into(),
Token::Neq => "'!='".into(),
Token::Lt => "'<'".into(),
Token::Gt => "'>'".into(),
Token::Lte => "'<='".into(),
Token::Gte => "'>='".into(),
Token::Assign => "':='".into(),
Token::Arrow => "'->'".into(),
Token::Pipe => "'|'".into(),
Token::Coalesce => "'??'".into(),
Token::Plus => "'+'".into(),
Token::Minus => "'-'".into(),
Token::Star => "'*'".into(),
Token::Slash => "'/'".into(),
Token::LBrace => "'{'".into(),
Token::RBrace => "'}'".into(),
Token::LParen => "'('".into(),
Token::RParen => "')'".into(),
Token::Comma => "','".into(),
Token::Colon => "':'".into(),
Token::Dot => "'.'".into(),
Token::Eof => "end of input".into(),
}
}
pub fn keyword_str(&self) -> Option<&'static str> {
Some(match self {
Token::Type => "type",
Token::Filter => "filter",
Token::Order => "order",
Token::Limit => "limit",
Token::Offset => "offset",
Token::Insert => "insert",
Token::Update => "update",
Token::Delete => "delete",
Token::Upsert => "upsert",
Token::Returning => "returning",
Token::Select => "select",
Token::Required => "required",
Token::Default => "default",
Token::Auto => "auto",
Token::Multi => "multi",
Token::Link => "link",
Token::Index => "index",
Token::Unique => "unique",
Token::On => "on",
Token::Conflict => "conflict",
Token::Asc => "asc",
Token::Desc => "desc",
Token::And => "and",
Token::Or => "or",
Token::Not => "not",
Token::Exists => "exists",
Token::Let => "let",
Token::As => "as",
Token::Match => "match",
Token::Group => "group",
Token::Join => "join",
Token::Inner => "inner",
Token::LeftKw => "left",
Token::RightKw => "right",
Token::Outer => "outer",
Token::Cross => "cross",
Token::Transaction => "transaction",
Token::Begin => "begin",
Token::Commit => "commit",
Token::Rollback => "rollback",
Token::View => "view",
Token::Materialized => "materialized",
Token::Refresh => "refresh",
Token::Union => "union",
Token::Having => "having",
Token::Distinct => "distinct",
Token::In => "in",
Token::Between => "between",
Token::Like => "like",
Token::Count => "count",
Token::Avg => "avg",
Token::Sum => "sum",
Token::Min => "min",
Token::Max => "max",
Token::Is => "is",
Token::Null => "null",
Token::Upper => "upper",
Token::Lower => "lower",
Token::Length => "length",
Token::Trim => "trim",
Token::Substring => "substring",
Token::Concat => "concat",
Token::Abs => "abs",
Token::Round => "round",
Token::Ceil => "ceil",
Token::Floor => "floor",
Token::Sqrt => "sqrt",
Token::Pow => "pow",
Token::Now => "now",
Token::Extract => "extract",
Token::DateAdd => "date_add",
Token::DateDiff => "date_diff",
Token::Cast => "cast",
Token::Case => "case",
Token::When => "when",
Token::Then => "then",
Token::Else => "else",
Token::End => "end",
Token::Over => "over",
Token::Partition => "partition",
Token::RowNumber => "row_number",
Token::Rank => "rank",
Token::DenseRank => "dense_rank",
Token::Alter => "alter",
Token::Drop => "drop",
Token::Add => "add",
Token::Column => "column",
Token::Explain => "explain",
Token::Schema => "schema",
Token::Describe => "describe",
_ => return None,
})
}
}