drizzle_core/sql/
chunk.rs1use crate::prelude::*;
2use crate::{Param, Placeholder, SQLColumnInfo, SQLParam, SQLTableInfo, sql::tokens::Token};
3
4#[derive(Clone)]
15pub enum SQLChunk<'a, V: SQLParam> {
16 Token(Token),
19
20 Ident(Cow<'a, str>),
24
25 Raw(Cow<'a, str>),
29
30 Param(Param<'a, V>),
33
34 Table(&'static dyn SQLTableInfo),
38
39 Column(&'static dyn SQLColumnInfo),
43
44 Alias {
47 inner: Box<SQLChunk<'a, V>>,
48 alias: Cow<'a, str>,
49 },
50}
51
52impl<'a, V: SQLParam> SQLChunk<'a, V> {
53 #[inline]
57 pub const fn token(t: Token) -> Self {
58 Self::Token(t)
59 }
60
61 #[inline]
63 pub const fn ident_static(name: &'static str) -> Self {
64 Self::Ident(Cow::Borrowed(name))
65 }
66
67 #[inline]
69 pub const fn raw_static(text: &'static str) -> Self {
70 Self::Raw(Cow::Borrowed(text))
71 }
72
73 #[inline]
75 pub const fn table(table: &'static dyn SQLTableInfo) -> Self {
76 Self::Table(table)
77 }
78
79 #[inline]
81 pub const fn column(column: &'static dyn SQLColumnInfo) -> Self {
82 Self::Column(column)
83 }
84
85 #[inline]
87 pub const fn param_borrowed(value: &'a V, placeholder: Placeholder) -> Self {
88 Self::Param(Param {
89 value: Some(Cow::Borrowed(value)),
90 placeholder,
91 })
92 }
93
94 #[inline]
98 pub fn ident(name: impl Into<Cow<'a, str>>) -> Self {
99 Self::Ident(name.into())
100 }
101
102 #[inline]
104 pub fn raw(text: impl Into<Cow<'a, str>>) -> Self {
105 Self::Raw(text.into())
106 }
107
108 #[inline]
110 pub fn param(value: impl Into<Cow<'a, V>>, placeholder: Placeholder) -> Self {
111 Self::Param(Param {
112 value: Some(value.into()),
113 placeholder,
114 })
115 }
116
117 #[inline]
119 pub fn alias(inner: SQLChunk<'a, V>, alias: impl Into<Cow<'a, str>>) -> Self {
120 Self::Alias {
121 inner: Box::new(inner),
122 alias: alias.into(),
123 }
124 }
125
126 pub(crate) fn write(&self, buf: &mut impl core::fmt::Write) {
130 match self {
131 SQLChunk::Token(token) => {
132 let _ = buf.write_str(token.as_str());
133 }
134 SQLChunk::Ident(name) => {
135 let _ = buf.write_char('"');
136 let _ = buf.write_str(name);
137 let _ = buf.write_char('"');
138 }
139 SQLChunk::Raw(text) => {
140 let _ = buf.write_str(text);
141 }
142 SQLChunk::Param(Param { placeholder, .. }) => {
143 let _ = write!(buf, "{}", placeholder);
144 }
145 SQLChunk::Table(table) => {
146 let _ = buf.write_char('"');
147 let _ = buf.write_str(table.name());
148 let _ = buf.write_char('"');
149 }
150 SQLChunk::Column(column) => {
151 let _ = buf.write_char('"');
152 let _ = buf.write_str(column.table().name());
153 let _ = buf.write_str("\".\"");
154 let _ = buf.write_str(column.name());
155 let _ = buf.write_char('"');
156 }
157 SQLChunk::Alias { inner, alias } => {
158 inner.write(buf);
159 let _ = buf.write_str(" AS \"");
160 let _ = buf.write_str(alias);
161 let _ = buf.write_char('"');
162 }
163 }
164 }
165
166 #[inline]
168 pub(crate) const fn is_word_like(&self) -> bool {
169 match self {
170 SQLChunk::Token(t) => !t.is_punctuation() && !t.is_operator(),
171 SQLChunk::Ident(_)
172 | SQLChunk::Raw(_)
173 | SQLChunk::Param(_)
174 | SQLChunk::Table(_)
175 | SQLChunk::Column(_)
176 | SQLChunk::Alias { .. } => true,
177 }
178 }
179}
180
181impl<'a, V: SQLParam + core::fmt::Debug> core::fmt::Debug for SQLChunk<'a, V> {
182 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
183 match self {
184 SQLChunk::Token(token) => f.debug_tuple("Token").field(token).finish(),
185 SQLChunk::Ident(name) => f.debug_tuple("Ident").field(name).finish(),
186 SQLChunk::Raw(text) => f.debug_tuple("Raw").field(text).finish(),
187 SQLChunk::Param(param) => f.debug_tuple("Param").field(param).finish(),
188 SQLChunk::Table(table) => f.debug_tuple("Table").field(&table.name()).finish(),
189 SQLChunk::Column(column) => f
190 .debug_tuple("Column")
191 .field(&format!("{}.{}", column.table().name(), column.name()))
192 .finish(),
193 SQLChunk::Alias { inner, alias } => f
194 .debug_struct("Alias")
195 .field("inner", inner)
196 .field("alias", alias)
197 .finish(),
198 }
199 }
200}
201
202impl<'a, V: SQLParam> From<Token> for SQLChunk<'a, V> {
205 #[inline]
206 fn from(value: Token) -> Self {
207 Self::Token(value)
208 }
209}
210
211impl<'a, V: SQLParam> From<&'static dyn SQLColumnInfo> for SQLChunk<'a, V> {
212 #[inline]
213 fn from(value: &'static dyn SQLColumnInfo) -> Self {
214 Self::Column(value)
215 }
216}
217
218impl<'a, V: SQLParam> From<&'static dyn SQLTableInfo> for SQLChunk<'a, V> {
219 #[inline]
220 fn from(value: &'static dyn SQLTableInfo) -> Self {
221 Self::Table(value)
222 }
223}
224
225impl<'a, V: SQLParam> From<Param<'a, V>> for SQLChunk<'a, V> {
226 #[inline]
227 fn from(value: Param<'a, V>) -> Self {
228 Self::Param(value)
229 }
230}