quaint_forked/ast/
row.rs

1#[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
2use super::compare::JsonType;
3use crate::ast::{Comparable, Compare, Expression};
4use std::borrow::Cow;
5
6/// A collection of values surrounded by parentheses.
7#[derive(Debug, Default, PartialEq, Clone)]
8pub struct Row<'a> {
9    pub values: Vec<Expression<'a>>,
10}
11
12impl<'a> Row<'a> {
13    pub fn new() -> Self {
14        Row { values: Vec::new() }
15    }
16
17    pub fn with_capacity(capacity: usize) -> Self {
18        Row {
19            values: Vec::with_capacity(capacity),
20        }
21    }
22
23    pub fn pop(&mut self) -> Option<Expression<'a>> {
24        self.values.pop()
25    }
26
27    pub fn push<T>(&mut self, value: T)
28    where
29        T: Into<Expression<'a>>,
30    {
31        self.values.push(value.into());
32    }
33
34    pub fn is_empty(&self) -> bool {
35        self.values.is_empty()
36    }
37
38    pub fn len(&self) -> usize {
39        self.values.len()
40    }
41
42    #[cfg(feature = "mssql")]
43    pub(crate) fn is_only_columns(&self) -> bool {
44        self.values.iter().all(|v| v.is_column())
45    }
46
47    #[cfg(feature = "mssql")]
48    pub(crate) fn into_columns(self) -> Vec<crate::ast::Column<'a>> {
49        let mut columns = Vec::with_capacity(self.len());
50
51        for expr in self.values.into_iter() {
52            columns.push(expr.into_column().unwrap());
53        }
54
55        columns
56    }
57}
58
59impl<'a> IntoIterator for Row<'a> {
60    type Item = Expression<'a>;
61    type IntoIter = std::vec::IntoIter<Self::Item>;
62
63    fn into_iter(self) -> Self::IntoIter {
64        self.values.into_iter()
65    }
66}
67
68impl<'a, T> From<Vec<T>> for Row<'a>
69where
70    T: Into<Expression<'a>>,
71{
72    fn from(vector: Vec<T>) -> Row<'a> {
73        let mut row = Row::with_capacity(vector.len());
74
75        for v in vector.into_iter() {
76            row.push(v.into());
77        }
78
79        row
80    }
81}
82
83impl<'a, A> From<(A,)> for Row<'a>
84where
85    A: Into<Expression<'a>>,
86{
87    fn from((val,): (A,)) -> Self {
88        let mut row = Row::with_capacity(1);
89        row.push(val);
90        row
91    }
92}
93
94impl<'a, A, B> From<(A, B)> for Row<'a>
95where
96    A: Into<Expression<'a>>,
97    B: Into<Expression<'a>>,
98{
99    fn from(vals: (A, B)) -> Self {
100        let mut row = Row::with_capacity(2);
101
102        row.push(vals.0);
103        row.push(vals.1);
104
105        row
106    }
107}
108
109impl<'a, A, B, C> From<(A, B, C)> for Row<'a>
110where
111    A: Into<Expression<'a>>,
112    B: Into<Expression<'a>>,
113    C: Into<Expression<'a>>,
114{
115    fn from(vals: (A, B, C)) -> Self {
116        let mut row = Row::with_capacity(3);
117
118        row.push(vals.0);
119        row.push(vals.1);
120        row.push(vals.2);
121
122        row
123    }
124}
125
126impl<'a, A, B, C, D> From<(A, B, C, D)> for Row<'a>
127where
128    A: Into<Expression<'a>>,
129    B: Into<Expression<'a>>,
130    C: Into<Expression<'a>>,
131    D: Into<Expression<'a>>,
132{
133    fn from(vals: (A, B, C, D)) -> Self {
134        let mut row = Row::with_capacity(4);
135
136        row.push(vals.0);
137        row.push(vals.1);
138        row.push(vals.2);
139        row.push(vals.3);
140
141        row
142    }
143}
144
145impl<'a, A, B, C, D, E> From<(A, B, C, D, E)> for Row<'a>
146where
147    A: Into<Expression<'a>>,
148    B: Into<Expression<'a>>,
149    C: Into<Expression<'a>>,
150    D: Into<Expression<'a>>,
151    E: Into<Expression<'a>>,
152{
153    fn from(vals: (A, B, C, D, E)) -> Self {
154        let mut row = Row::with_capacity(5);
155
156        row.push(vals.0);
157        row.push(vals.1);
158        row.push(vals.2);
159        row.push(vals.3);
160        row.push(vals.4);
161
162        row
163    }
164}
165
166impl<'a> Comparable<'a> for Row<'a> {
167    fn equals<T>(self, comparison: T) -> Compare<'a>
168    where
169        T: Into<Expression<'a>>,
170    {
171        let value: Expression<'a> = self.into();
172        value.equals(comparison)
173    }
174
175    fn not_equals<T>(self, comparison: T) -> Compare<'a>
176    where
177        T: Into<Expression<'a>>,
178    {
179        let value: Expression<'a> = self.into();
180        value.not_equals(comparison)
181    }
182
183    fn less_than<T>(self, comparison: T) -> Compare<'a>
184    where
185        T: Into<Expression<'a>>,
186    {
187        let value: Expression<'a> = self.into();
188        value.less_than(comparison)
189    }
190
191    fn less_than_or_equals<T>(self, comparison: T) -> Compare<'a>
192    where
193        T: Into<Expression<'a>>,
194    {
195        let value: Expression<'a> = self.into();
196        value.less_than_or_equals(comparison)
197    }
198
199    fn greater_than<T>(self, comparison: T) -> Compare<'a>
200    where
201        T: Into<Expression<'a>>,
202    {
203        let value: Expression<'a> = self.into();
204        value.greater_than(comparison)
205    }
206
207    fn greater_than_or_equals<T>(self, comparison: T) -> Compare<'a>
208    where
209        T: Into<Expression<'a>>,
210    {
211        let value: Expression<'a> = self.into();
212        value.greater_than_or_equals(comparison)
213    }
214
215    fn in_selection<T>(self, selection: T) -> Compare<'a>
216    where
217        T: Into<Expression<'a>>,
218    {
219        let value: Expression<'a> = self.into();
220        value.in_selection(selection)
221    }
222
223    fn not_in_selection<T>(self, selection: T) -> Compare<'a>
224    where
225        T: Into<Expression<'a>>,
226    {
227        let value: Expression<'a> = self.into();
228        value.not_in_selection(selection)
229    }
230
231    fn like<T>(self, pattern: T) -> Compare<'a>
232    where
233        T: Into<Expression<'a>>,
234    {
235        let value: Expression<'a> = self.into();
236        value.like(pattern)
237    }
238
239    fn not_like<T>(self, pattern: T) -> Compare<'a>
240    where
241        T: Into<Expression<'a>>,
242    {
243        let value: Expression<'a> = self.into();
244        value.not_like(pattern)
245    }
246
247    #[allow(clippy::wrong_self_convention)]
248    fn is_null(self) -> Compare<'a> {
249        let value: Expression<'a> = self.into();
250        value.is_null()
251    }
252
253    #[allow(clippy::wrong_self_convention)]
254    fn is_not_null(self) -> Compare<'a> {
255        let value: Expression<'a> = self.into();
256        value.is_not_null()
257    }
258
259    fn between<T, V>(self, left: T, right: V) -> Compare<'a>
260    where
261        T: Into<Expression<'a>>,
262        V: Into<Expression<'a>>,
263    {
264        let value: Expression<'a> = self.into();
265        value.between(left, right)
266    }
267
268    fn not_between<T, V>(self, left: T, right: V) -> Compare<'a>
269    where
270        T: Into<Expression<'a>>,
271        V: Into<Expression<'a>>,
272    {
273        let value: Expression<'a> = self.into();
274        value.not_between(left, right)
275    }
276
277    fn compare_raw<T, V>(self, raw_comparator: T, right: V) -> Compare<'a>
278    where
279        T: Into<Cow<'a, str>>,
280        V: Into<Expression<'a>>,
281    {
282        let value: Expression<'a> = self.into();
283        value.compare_raw(raw_comparator, right)
284    }
285
286    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
287    fn json_array_contains<T>(self, item: T) -> Compare<'a>
288    where
289        T: Into<Expression<'a>>,
290    {
291        let value: Expression<'a> = self.into();
292
293        value.json_array_contains(item)
294    }
295
296    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
297    fn json_array_not_contains<T>(self, item: T) -> Compare<'a>
298    where
299        T: Into<Expression<'a>>,
300    {
301        let value: Expression<'a> = self.into();
302
303        value.json_array_not_contains(item)
304    }
305
306    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
307    fn json_array_begins_with<T>(self, item: T) -> Compare<'a>
308    where
309        T: Into<Expression<'a>>,
310    {
311        let value: Expression<'a> = self.into();
312
313        value.json_array_begins_with(item)
314    }
315
316    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
317    fn json_array_not_begins_with<T>(self, item: T) -> Compare<'a>
318    where
319        T: Into<Expression<'a>>,
320    {
321        let value: Expression<'a> = self.into();
322
323        value.json_array_not_begins_with(item)
324    }
325
326    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
327    fn json_array_ends_into<T>(self, item: T) -> Compare<'a>
328    where
329        T: Into<Expression<'a>>,
330    {
331        let value: Expression<'a> = self.into();
332
333        value.json_array_ends_into(item)
334    }
335
336    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
337    fn json_array_not_ends_into<T>(self, item: T) -> Compare<'a>
338    where
339        T: Into<Expression<'a>>,
340    {
341        let value: Expression<'a> = self.into();
342
343        value.json_array_not_ends_into(item)
344    }
345
346    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
347    fn json_type_equals<T>(self, json_type: T) -> Compare<'a>
348    where
349        T: Into<JsonType<'a>>,
350    {
351        let value: Expression<'a> = self.into();
352
353        value.json_type_equals(json_type)
354    }
355
356    #[cfg(all(feature = "json", any(feature = "postgresql", feature = "mysql")))]
357    fn json_type_not_equals<T>(self, json_type: T) -> Compare<'a>
358    where
359        T: Into<JsonType<'a>>,
360    {
361        let value: Expression<'a> = self.into();
362
363        value.json_type_not_equals(json_type)
364    }
365
366    #[cfg(feature = "postgresql")]
367    fn matches<T>(self, query: T) -> Compare<'a>
368    where
369        T: Into<Cow<'a, str>>,
370    {
371        let value: Expression<'a> = self.into();
372
373        value.matches(query)
374    }
375
376    #[cfg(feature = "postgresql")]
377    fn not_matches<T>(self, query: T) -> Compare<'a>
378    where
379        T: Into<Cow<'a, str>>,
380    {
381        let value: Expression<'a> = self.into();
382
383        value.not_matches(query)
384    }
385
386    #[cfg(feature = "postgresql")]
387    fn any(self) -> Compare<'a> {
388        let value: Expression<'a> = self.into();
389
390        value.any()
391    }
392
393    #[cfg(feature = "postgresql")]
394    fn all(self) -> Compare<'a> {
395        let value: Expression<'a> = self.into();
396
397        value.all()
398    }
399}