surrealdb_core/sql/
array.rs1use crate::ctx::Context;
2use crate::dbs::Options;
3use crate::doc::CursorDoc;
4use crate::err::Error;
5use crate::sql::{
6 fmt::{pretty_indent, Fmt, Pretty},
7 Number, Operation, Value,
8};
9use reblessive::tree::Stk;
10use revision::revisioned;
11use serde::{Deserialize, Serialize};
12use std::collections::HashSet;
13use std::fmt::{self, Display, Formatter, Write};
14use std::ops;
15use std::ops::Deref;
16use std::ops::DerefMut;
17
18pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Array";
19
20#[revisioned(revision = 1)]
21#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
22#[serde(rename = "$surrealdb::private::sql::Array")]
23#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
24#[non_exhaustive]
25pub struct Array(pub Vec<Value>);
26
27impl From<Value> for Array {
28 fn from(v: Value) -> Self {
29 vec![v].into()
30 }
31}
32
33impl From<Vec<Value>> for Array {
34 fn from(v: Vec<Value>) -> Self {
35 Self(v)
36 }
37}
38
39impl From<Vec<i32>> for Array {
40 fn from(v: Vec<i32>) -> Self {
41 Self(v.into_iter().map(Value::from).collect())
42 }
43}
44
45impl From<Vec<f64>> for Array {
46 fn from(v: Vec<f64>) -> Self {
47 Self(v.into_iter().map(Value::from).collect())
48 }
49}
50
51impl From<Vec<&str>> for Array {
52 fn from(v: Vec<&str>) -> Self {
53 Self(v.into_iter().map(Value::from).collect())
54 }
55}
56
57impl From<Vec<String>> for Array {
58 fn from(v: Vec<String>) -> Self {
59 Self(v.into_iter().map(Value::from).collect())
60 }
61}
62
63impl From<Vec<Number>> for Array {
64 fn from(v: Vec<Number>) -> Self {
65 Self(v.into_iter().map(Value::from).collect())
66 }
67}
68
69impl From<Vec<Operation>> for Array {
70 fn from(v: Vec<Operation>) -> Self {
71 Self(v.into_iter().map(Value::from).collect())
72 }
73}
74
75impl From<Vec<bool>> for Array {
76 fn from(v: Vec<bool>) -> Self {
77 Self(v.into_iter().map(Value::from).collect())
78 }
79}
80
81impl From<Array> for Vec<Value> {
82 fn from(s: Array) -> Self {
83 s.0
84 }
85}
86
87impl FromIterator<Value> for Array {
88 fn from_iter<I: IntoIterator<Item = Value>>(iter: I) -> Self {
89 Array(iter.into_iter().collect())
90 }
91}
92
93impl Deref for Array {
94 type Target = Vec<Value>;
95 fn deref(&self) -> &Self::Target {
96 &self.0
97 }
98}
99
100impl DerefMut for Array {
101 fn deref_mut(&mut self) -> &mut Self::Target {
102 &mut self.0
103 }
104}
105
106impl IntoIterator for Array {
107 type Item = Value;
108 type IntoIter = std::vec::IntoIter<Self::Item>;
109 fn into_iter(self) -> Self::IntoIter {
110 self.0.into_iter()
111 }
112}
113
114impl Array {
115 pub fn new() -> Self {
117 Self::default()
118 }
119 pub fn with_capacity(len: usize) -> Self {
121 Self(Vec::with_capacity(len))
122 }
123 pub fn len(&self) -> usize {
125 self.0.len()
126 }
127 pub fn is_empty(&self) -> bool {
129 self.0.is_empty()
130 }
131}
132
133impl Array {
134 pub(crate) async fn compute(
136 &self,
137 stk: &mut Stk,
138 ctx: &Context<'_>,
139 opt: &Options,
140 doc: Option<&CursorDoc<'_>>,
141 ) -> Result<Value, Error> {
142 let mut x = Self::with_capacity(self.len());
143 for v in self.iter() {
144 match v.compute(stk, ctx, opt, doc).await {
145 Ok(v) => x.push(v),
146 Err(e) => return Err(e),
147 };
148 }
149 Ok(Value::Array(x))
150 }
151
152 pub(crate) fn is_all_none_or_null(&self) -> bool {
153 self.0.iter().all(|v| v.is_none_or_null())
154 }
155
156 pub(crate) fn is_static(&self) -> bool {
157 self.iter().all(Value::is_static)
158 }
159}
160
161impl Display for Array {
162 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
163 let mut f = Pretty::from(f);
164 f.write_char('[')?;
165 if !self.is_empty() {
166 let indent = pretty_indent();
167 write!(f, "{}", Fmt::pretty_comma_separated(self.as_slice()))?;
168 drop(indent);
169 }
170 f.write_char(']')
171 }
172}
173
174impl ops::Add<Value> for Array {
177 type Output = Self;
178 fn add(mut self, other: Value) -> Self {
179 self.0.push(other);
180 self
181 }
182}
183
184impl ops::Add for Array {
185 type Output = Self;
186 fn add(mut self, mut other: Self) -> Self {
187 self.0.append(&mut other.0);
188 self
189 }
190}
191
192impl ops::Sub<Value> for Array {
195 type Output = Self;
196 fn sub(mut self, other: Value) -> Self {
197 if let Some(p) = self.0.iter().position(|x| *x == other) {
198 self.0.remove(p);
199 }
200 self
201 }
202}
203
204impl ops::Sub for Array {
205 type Output = Self;
206 fn sub(mut self, other: Self) -> Self {
207 for v in other.0 {
208 if let Some(p) = self.0.iter().position(|x| *x == v) {
209 self.0.remove(p);
210 }
211 }
212 self
213 }
214}
215
216pub trait Abolish<T> {
219 fn abolish<F>(&mut self, f: F)
220 where
221 F: FnMut(usize) -> bool;
222}
223
224impl<T> Abolish<T> for Vec<T> {
225 fn abolish<F>(&mut self, mut f: F)
226 where
227 F: FnMut(usize) -> bool,
228 {
229 let mut i = 0;
230 self.retain(|_| {
233 let retain = !f(i);
234 i += 1;
235 retain
236 });
237 }
238}
239
240pub(crate) trait Clump<T> {
243 fn clump(self, clump_size: usize) -> T;
244}
245
246impl Clump<Array> for Array {
247 fn clump(self, clump_size: usize) -> Array {
248 self.0
249 .chunks(clump_size)
250 .map::<Value, _>(|chunk| chunk.to_vec().into())
251 .collect::<Vec<_>>()
252 .into()
253 }
254}
255
256pub(crate) trait Combine<T> {
259 fn combine(self, other: T) -> T;
260}
261
262impl Combine<Array> for Array {
263 fn combine(self, other: Self) -> Array {
264 let mut out = Self::with_capacity(self.len().saturating_mul(other.len()));
265 for a in self.iter() {
266 for b in other.iter() {
267 out.push(vec![a.clone(), b.clone()].into());
268 }
269 }
270 out
271 }
272}
273
274pub(crate) trait Complement<T> {
277 fn complement(self, other: T) -> T;
278}
279
280impl Complement<Array> for Array {
281 fn complement(self, other: Self) -> Array {
282 let mut out = Array::new();
283 for v in self.into_iter() {
284 if !other.contains(&v) {
285 out.push(v)
286 }
287 }
288 out
289 }
290}
291
292#[allow(dead_code)]
295pub(crate) trait Concat<T> {
296 fn concat(self, other: T) -> T;
297}
298
299impl Concat<Array> for Array {
300 fn concat(mut self, mut other: Array) -> Array {
301 self.append(&mut other);
302 self
303 }
304}
305
306impl Concat<String> for String {
307 fn concat(self, other: String) -> String {
308 self + &other
309 }
310}
311
312pub(crate) trait Difference<T> {
315 fn difference(self, other: T) -> T;
316}
317
318impl Difference<Array> for Array {
319 fn difference(self, mut other: Array) -> Array {
320 let mut out = Array::new();
321 for v in self.into_iter() {
322 if let Some(pos) = other.iter().position(|w| v == *w) {
323 other.remove(pos);
324 } else {
325 out.push(v);
326 }
327 }
328 out.append(&mut other);
329 out
330 }
331}
332
333pub(crate) trait Flatten<T> {
336 fn flatten(self) -> T;
337}
338
339impl Flatten<Array> for Array {
340 fn flatten(self) -> Array {
341 let mut out = Array::new();
342 for v in self.into_iter() {
343 match v {
344 Value::Array(mut a) => out.append(&mut a),
345 _ => out.push(v),
346 }
347 }
348 out
349 }
350}
351
352pub(crate) trait Intersect<T> {
355 fn intersect(self, other: T) -> T;
356}
357
358impl Intersect<Self> for Array {
359 fn intersect(self, mut other: Self) -> Self {
360 let mut out = Self::new();
361 for v in self.0.into_iter() {
362 if let Some(pos) = other.iter().position(|w| v == *w) {
363 other.remove(pos);
364 out.push(v);
365 }
366 }
367 out
368 }
369}
370
371pub(crate) trait Matches<T> {
375 fn matches(self, compare_val: Value) -> T;
382}
383
384impl Matches<Array> for Array {
385 fn matches(self, compare_val: Value) -> Array {
386 self.iter().map(|arr_val| (arr_val == &compare_val).into()).collect::<Vec<Value>>().into()
387 }
388}
389
390pub(crate) trait Transpose<T> {
394 fn transpose(self) -> T;
426}
427
428impl Transpose<Array> for Array {
429 fn transpose(self) -> Array {
430 if self.is_empty() {
431 return self;
432 }
433 let mut transposed_vec = Vec::<Value>::with_capacity(self.len());
436 let mut iters = self
437 .iter()
438 .map(|v| {
439 if let Value::Array(arr) = v {
440 Box::new(arr.iter().cloned()) as Box<dyn ExactSizeIterator<Item = Value>>
441 } else {
442 Box::new(std::iter::once(v).cloned())
443 as Box<dyn ExactSizeIterator<Item = Value>>
444 }
445 })
446 .collect::<Vec<_>>();
447 let longest_length = iters.iter().map(|i| i.len()).max().unwrap();
450 for _ in 0..longest_length {
451 transposed_vec
452 .push(iters.iter_mut().filter_map(|i| i.next()).collect::<Vec<_>>().into());
453 }
454 transposed_vec.into()
455 }
456}
457
458pub(crate) trait Union<T> {
461 fn union(self, other: T) -> T;
462}
463
464impl Union<Self> for Array {
465 fn union(mut self, mut other: Self) -> Array {
466 self.append(&mut other);
467 self.uniq()
468 }
469}
470
471pub(crate) trait Uniq<T> {
474 fn uniq(self) -> T;
475}
476
477impl Uniq<Array> for Array {
478 fn uniq(mut self) -> Array {
479 let mut set: HashSet<&Value> = HashSet::new();
480 let mut to_remove: Vec<usize> = Vec::new();
481 for (i, item) in self.iter().enumerate() {
482 if !set.insert(item) {
483 to_remove.push(i);
484 }
485 }
486 for i in to_remove.iter().rev() {
487 self.remove(*i);
488 }
489 self
490 }
491}