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