sqlite3_parser/parser/
mod.rs1pub mod ast;
4pub mod parse {
5 #![expect(unused_braces)]
6 #![expect(clippy::if_same_then_else)]
7 #![expect(clippy::absurd_extreme_comparisons)] #![expect(clippy::needless_return)]
9 #![expect(clippy::upper_case_acronyms)]
10 #![expect(clippy::manual_range_patterns)]
11
12 include!(concat!(env!("OUT_DIR"), "/parse.rs"));
13}
14
15use crate::dialect::Token;
16use ast::{Cmd, ExplainKind, Name, Stmt};
17
18#[derive(Debug, PartialEq)]
20pub enum ParserError {
21 SyntaxError(Box<str>),
23 UnexpectedEof,
25 Custom(String),
27}
28
29impl std::fmt::Display for ParserError {
30 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
31 match self {
32 Self::SyntaxError(s) => {
33 write!(f, "near \"{s}\": syntax error")
34 }
35 Self::UnexpectedEof => f.write_str("unexpected end of input"),
36 Self::Custom(s) => f.write_str(s),
37 }
38 }
39}
40
41impl std::error::Error for ParserError {}
42
43#[macro_export]
45macro_rules! custom_err {
46 ($msg:literal $(,)?) => {
47 $crate::parser::ParserError::Custom($msg.to_owned())
48 };
49 ($err:expr $(,)?) => {
50 $crate::parser::ParserError::Custom(format!($err))
51 };
52 ($fmt:expr, $($arg:tt)*) => {
53 $crate::parser::ParserError::Custom(format!($fmt, $($arg)*))
54 };
55}
56
57pub struct Context<'input> {
59 input: &'input [u8],
60 explain: Option<ExplainKind>,
61 stmt: Option<Stmt>,
62 constraint_name: Option<Name>, module_arg: Option<(usize, usize)>, module_args: Option<Vec<Box<str>>>, done: bool,
66 error: Option<ParserError>,
67}
68
69impl<'input> Context<'input> {
70 pub fn new(input: &'input [u8]) -> Self {
71 Context {
72 input,
73 explain: None,
74 stmt: None,
75 constraint_name: None,
76 module_arg: None,
77 module_args: None,
78 done: false,
79 error: None,
80 }
81 }
82
83 pub fn cmd(&mut self) -> Option<Cmd> {
85 if let Some(stmt) = self.stmt.take() {
86 match self.explain.take() {
87 Some(ExplainKind::Explain) => Some(Cmd::Explain(stmt)),
88 Some(ExplainKind::QueryPlan) => Some(Cmd::ExplainQueryPlan(stmt)),
89 None => Some(Cmd::Stmt(stmt)),
90 }
91 } else {
92 None
93 }
94 }
95
96 fn constraint_name(&mut self) -> Option<Name> {
97 self.constraint_name.take()
98 }
99 fn no_constraint_name(&self) -> bool {
100 self.constraint_name.is_none()
101 }
102
103 fn vtab_arg_init(&mut self) {
104 self.add_module_arg();
105 self.module_arg = None;
106 }
107 fn vtab_arg_extend(&mut self, any: Token) {
108 if let Some((_, ref mut n)) = self.module_arg {
109 *n = any.2
110 } else {
111 self.module_arg = Some((any.0, any.2))
112 }
113 }
114 fn add_module_arg(&mut self) {
115 if let Some((start, end)) = self.module_arg.take() {
116 if let Ok(arg) = std::str::from_utf8(&self.input[start..end]) {
117 self.module_args.get_or_insert(vec![]).push(arg.into());
118 } }
120 }
121 fn module_args(&mut self) -> Option<Vec<Box<str>>> {
122 self.add_module_arg();
123 self.module_args.take()
124 }
125
126 fn sqlite3_finish_coding(&mut self) {
128 self.done = true;
129 }
130
131 pub fn done(&self) -> bool {
133 self.done || self.error.is_some()
134 }
135
136 pub fn is_ok(&self) -> bool {
137 self.error.is_none()
138 }
139
140 pub fn error(&mut self) -> Option<ParserError> {
142 self.error.take()
143 }
144
145 pub fn reset(&mut self) {
146 self.explain = None;
147 self.stmt = None;
148 self.constraint_name = None;
149 self.module_arg = None;
150 self.module_args = None;
151 self.done = false;
152 self.error = None;
153 }
154}