drizzle_core/sql/
chunk.rs1use crate::prelude::*;
2use crate::{Param, Placeholder, SQLColumnInfo, SQLParam, SQLTableInfo, sql::tokens::Token};
3
4#[derive(Default, Clone)]
16pub enum SQLChunk<'a, V: SQLParam> {
17 #[default]
20 Empty,
21
22 Token(Token),
25
26 Ident(Cow<'a, str>),
30
31 Raw(Cow<'a, str>),
35
36 Param(Param<'a, V>),
39
40 Table(&'static dyn SQLTableInfo),
44
45 Column(&'static dyn SQLColumnInfo),
49
50 Alias {
53 inner: Box<SQLChunk<'a, V>>,
54 alias: Cow<'a, str>,
55 },
56}
57
58impl<'a, V: SQLParam> SQLChunk<'a, V> {
59 #[inline]
63 pub const fn token(t: Token) -> Self {
64 Self::Token(t)
65 }
66
67 #[inline]
69 pub const fn ident_static(name: &'static str) -> Self {
70 Self::Ident(Cow::Borrowed(name))
71 }
72
73 #[inline]
75 pub const fn raw_static(text: &'static str) -> Self {
76 Self::Raw(Cow::Borrowed(text))
77 }
78
79 #[inline]
81 pub const fn table(table: &'static dyn SQLTableInfo) -> Self {
82 Self::Table(table)
83 }
84
85 #[inline]
87 pub const fn column(column: &'static dyn SQLColumnInfo) -> Self {
88 Self::Column(column)
89 }
90
91 #[inline]
93 pub const fn param_borrowed(value: &'a V, placeholder: Placeholder) -> Self {
94 Self::Param(Param {
95 value: Some(Cow::Borrowed(value)),
96 placeholder,
97 })
98 }
99
100 #[inline]
104 pub fn ident(name: impl Into<Cow<'a, str>>) -> Self {
105 Self::Ident(name.into())
106 }
107
108 #[inline]
110 pub fn raw(text: impl Into<Cow<'a, str>>) -> Self {
111 Self::Raw(text.into())
112 }
113
114 #[inline]
116 pub fn param(value: impl Into<Cow<'a, V>>, placeholder: Placeholder) -> Self {
117 Self::Param(Param {
118 value: Some(value.into()),
119 placeholder,
120 })
121 }
122
123 #[inline]
125 pub fn alias(inner: SQLChunk<'a, V>, alias: impl Into<Cow<'a, str>>) -> Self {
126 Self::Alias {
127 inner: Box::new(inner),
128 alias: alias.into(),
129 }
130 }
131
132 pub(crate) fn write(&self, buf: &mut impl core::fmt::Write) {
136 match self {
137 SQLChunk::Empty => {} SQLChunk::Token(token) => {
139 let _ = buf.write_str(token.as_str());
140 }
141 SQLChunk::Ident(name) => {
142 let _ = buf.write_char('"');
143 let _ = buf.write_str(name);
144 let _ = buf.write_char('"');
145 }
146 SQLChunk::Raw(text) => {
147 let _ = buf.write_str(text);
148 }
149 SQLChunk::Param(Param { placeholder, .. }) => {
150 let _ = write!(buf, "{}", placeholder);
151 }
152 SQLChunk::Table(table) => {
153 let _ = buf.write_char('"');
154 let _ = buf.write_str(table.name());
155 let _ = buf.write_char('"');
156 }
157 SQLChunk::Column(column) => {
158 let _ = buf.write_char('"');
159 let _ = buf.write_str(column.table().name());
160 let _ = buf.write_str("\".\"");
161 let _ = buf.write_str(column.name());
162 let _ = buf.write_char('"');
163 }
164 SQLChunk::Alias { inner, alias } => {
165 inner.write(buf);
166 let _ = buf.write_str(" AS \"");
167 let _ = buf.write_str(alias);
168 let _ = buf.write_char('"');
169 }
170 }
171 }
172
173 #[inline]
175 pub(crate) fn is_word_like(&self) -> bool {
176 match self {
177 SQLChunk::Empty => false,
178 SQLChunk::Token(t) => !matches!(
179 t,
180 Token::LPAREN
181 | Token::RPAREN
182 | Token::COMMA
183 | Token::SEMI
184 | Token::DOT
185 | Token::EQ
186 | Token::NE
187 | Token::LT
188 | Token::GT
189 | Token::LE
190 | Token::GE
191 ),
192 SQLChunk::Ident(_)
193 | SQLChunk::Raw(_)
194 | SQLChunk::Param(_)
195 | SQLChunk::Table(_)
196 | SQLChunk::Column(_)
197 | SQLChunk::Alias { .. } => true,
198 }
199 }
200}
201
202impl<'a, V: SQLParam + core::fmt::Debug> core::fmt::Debug for SQLChunk<'a, V> {
203 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
204 match self {
205 SQLChunk::Empty => f.write_str("Empty"),
206 SQLChunk::Token(token) => f.debug_tuple("Token").field(token).finish(),
207 SQLChunk::Ident(name) => f.debug_tuple("Ident").field(name).finish(),
208 SQLChunk::Raw(text) => f.debug_tuple("Raw").field(text).finish(),
209 SQLChunk::Param(param) => f.debug_tuple("Param").field(param).finish(),
210 SQLChunk::Table(table) => f.debug_tuple("Table").field(&table.name()).finish(),
211 SQLChunk::Column(column) => f
212 .debug_tuple("Column")
213 .field(&format!("{}.{}", column.table().name(), column.name()))
214 .finish(),
215 SQLChunk::Alias { inner, alias } => f
216 .debug_struct("Alias")
217 .field("inner", inner)
218 .field("alias", alias)
219 .finish(),
220 }
221 }
222}
223
224impl<'a, V: SQLParam> From<Token> for SQLChunk<'a, V> {
227 #[inline]
228 fn from(value: Token) -> Self {
229 Self::Token(value)
230 }
231}
232
233impl<'a, V: SQLParam> From<&'static dyn SQLColumnInfo> for SQLChunk<'a, V> {
234 #[inline]
235 fn from(value: &'static dyn SQLColumnInfo) -> Self {
236 Self::Column(value)
237 }
238}
239
240impl<'a, V: SQLParam> From<&'static dyn SQLTableInfo> for SQLChunk<'a, V> {
241 #[inline]
242 fn from(value: &'static dyn SQLTableInfo) -> Self {
243 Self::Table(value)
244 }
245}
246
247impl<'a, V: SQLParam> From<Param<'a, V>> for SQLChunk<'a, V> {
248 #[inline]
249 fn from(value: Param<'a, V>) -> Self {
250 Self::Param(value)
251 }
252}