1use std::fmt;
2
3use crate::keywords::Keyword;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum MultiCharOperator {
9 LessEqual,
11 GreaterEqual,
13 NotEqual,
15 NotEqualAlt,
17 DoubleEqual,
19 Concat,
21 LeftShift,
23 RightShift,
25 JsonExtract,
27 JsonExtractText,
29 CosineDistance,
31 NegativeInnerProduct,
33 L2Distance,
35}
36
37impl fmt::Display for MultiCharOperator {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 match self {
40 MultiCharOperator::LessEqual => write!(f, "<="),
41 MultiCharOperator::GreaterEqual => write!(f, ">="),
42 MultiCharOperator::NotEqual => write!(f, "!="),
43 MultiCharOperator::NotEqualAlt => write!(f, "<>"),
44 MultiCharOperator::DoubleEqual => write!(f, "=="),
45 MultiCharOperator::Concat => write!(f, "||"),
46 MultiCharOperator::LeftShift => write!(f, "<<"),
47 MultiCharOperator::RightShift => write!(f, ">>"),
48 MultiCharOperator::JsonExtract => write!(f, "->"),
49 MultiCharOperator::JsonExtractText => write!(f, "->>"),
50 MultiCharOperator::CosineDistance => write!(f, "<->"),
51 MultiCharOperator::NegativeInnerProduct => write!(f, "<#>"),
52 MultiCharOperator::L2Distance => write!(f, "<=>"),
53 }
54 }
55}
56
57#[derive(Debug, Clone, PartialEq)]
59pub enum Token {
60 Keyword { keyword: Keyword, original: String },
64 Identifier(String),
66 DelimitedIdentifier(String),
68 Number(String),
70 String(String),
72 BlobLiteral(Vec<u8>),
74 Symbol(char),
76 Operator(MultiCharOperator),
78 SessionVariable(String),
80 UserVariable(String),
82 Placeholder,
85 NumberedPlaceholder(usize),
88 NamedPlaceholder(String),
91 Semicolon,
93 Comma,
95 LParen,
97 RParen,
99 Eof,
101}
102
103impl Token {
104 pub fn to_sql(&self) -> String {
107 match self {
108 Token::Keyword { keyword, .. } => keyword.to_string(),
109 Token::Identifier(id) => id.clone(),
110 Token::DelimitedIdentifier(id) => format!("\"{}\"", id),
111 Token::Number(n) => n.clone(),
112 Token::String(s) => format!("'{}'", s.replace('\'', "''")),
113 Token::BlobLiteral(bytes) => {
114 let hex: String = bytes.iter().map(|b| format!("{:02X}", b)).collect();
115 format!("x'{}'", hex)
116 }
117 Token::Symbol(c) => c.to_string(),
118 Token::Operator(op) => op.to_string(),
119 Token::SessionVariable(v) => format!("@@{}", v),
120 Token::UserVariable(v) => format!("@{}", v),
121 Token::Placeholder => "?".to_string(),
122 Token::NumberedPlaceholder(n) => format!("${}", n),
123 Token::NamedPlaceholder(name) => format!(":{}", name),
124 Token::Semicolon => ";".to_string(),
125 Token::Comma => ",".to_string(),
126 Token::LParen => "(".to_string(),
127 Token::RParen => ")".to_string(),
128 Token::Eof => String::new(),
129 }
130 }
131
132 pub fn syntax_error(&self) -> String {
141 match self {
142 Token::Eof => "incomplete input".to_string(),
144 Token::Keyword { original, .. } => {
146 format!("near \"{}\": syntax error", original)
147 }
148 _ => format!("near \"{}\": syntax error", self.to_sql()),
149 }
150 }
151}
152
153impl fmt::Display for Token {
154 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155 match self {
156 Token::Keyword { keyword, .. } => write!(f, "Keyword({})", keyword),
157 Token::Identifier(id) => write!(f, "Identifier({})", id),
158 Token::DelimitedIdentifier(id) => write!(f, "DelimitedIdentifier(\"{}\")", id),
159 Token::Number(n) => write!(f, "Number({})", n),
160 Token::String(s) => write!(f, "String('{}')", s),
161 Token::BlobLiteral(bytes) => {
162 let hex: String = bytes.iter().map(|b| format!("{:02X}", b)).collect();
163 write!(f, "BlobLiteral(x'{}')", hex)
164 }
165 Token::Symbol(c) => write!(f, "Symbol({})", c),
166 Token::Operator(op) => write!(f, "Operator({})", op),
167 Token::SessionVariable(v) => write!(f, "SessionVariable({})", v),
168 Token::UserVariable(v) => write!(f, "UserVariable({})", v),
169 Token::Placeholder => write!(f, "Placeholder"),
170 Token::NumberedPlaceholder(n) => write!(f, "NumberedPlaceholder(${})", n),
171 Token::NamedPlaceholder(name) => write!(f, "NamedPlaceholder(:{})", name),
172 Token::Semicolon => write!(f, "Semicolon"),
173 Token::Comma => write!(f, "Comma"),
174 Token::LParen => write!(f, "LParen"),
175 Token::RParen => write!(f, "RParen"),
176 Token::Eof => write!(f, "Eof"),
177 }
178 }
179}