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<f32>> for Array {
46 fn from(v: Vec<f32>) -> Self {
47 Self(v.into_iter().map(Value::from).collect())
48 }
49}
50
51impl From<Vec<f64>> for Array {
52 fn from(v: Vec<f64>) -> Self {
53 Self(v.into_iter().map(Value::from).collect())
54 }
55}
56
57impl From<Vec<usize>> for Array {
58 fn from(v: Vec<usize>) -> Self {
59 Self(v.into_iter().map(Value::from).collect())
60 }
61}
62
63impl From<Vec<&str>> for Array {
64 fn from(v: Vec<&str>) -> Self {
65 Self(v.into_iter().map(Value::from).collect())
66 }
67}
68
69impl From<Vec<String>> for Array {
70 fn from(v: Vec<String>) -> Self {
71 Self(v.into_iter().map(Value::from).collect())
72 }
73}
74
75impl From<Vec<Number>> for Array {
76 fn from(v: Vec<Number>) -> Self {
77 Self(v.into_iter().map(Value::from).collect())
78 }
79}
80
81impl From<Vec<Operation>> for Array {
82 fn from(v: Vec<Operation>) -> Self {
83 Self(v.into_iter().map(Value::from).collect())
84 }
85}
86
87impl From<Vec<bool>> for Array {
88 fn from(v: Vec<bool>) -> Self {
89 Self(v.into_iter().map(Value::from).collect())
90 }
91}
92
93impl From<Array> for Vec<Value> {
94 fn from(s: Array) -> Self {
95 s.0
96 }
97}
98
99impl FromIterator<Value> for Array {
100 fn from_iter<I: IntoIterator<Item = Value>>(iter: I) -> Self {
101 Array(iter.into_iter().collect())
102 }
103}
104
105impl Deref for Array {
106 type Target = Vec<Value>;
107 fn deref(&self) -> &Self::Target {
108 &self.0
109 }
110}
111
112impl DerefMut for Array {
113 fn deref_mut(&mut self) -> &mut Self::Target {
114 &mut self.0
115 }
116}
117
118impl IntoIterator for Array {
119 type Item = Value;
120 type IntoIter = std::vec::IntoIter<Self::Item>;
121 fn into_iter(self) -> Self::IntoIter {
122 self.0.into_iter()
123 }
124}
125
126impl Array {
127 pub fn new() -> Self {
129 Self::default()
130 }
131 pub fn with_capacity(len: usize) -> Self {
133 Self(Vec::with_capacity(len))
134 }
135 pub fn len(&self) -> usize {
137 self.0.len()
138 }
139 pub fn is_empty(&self) -> bool {
141 self.0.is_empty()
142 }
143}
144
145impl Array {
146 pub(crate) async fn compute(
148 &self,
149 stk: &mut Stk,
150 ctx: &Context,
151 opt: &Options,
152 doc: Option<&CursorDoc>,
153 ) -> Result<Value, Error> {
154 let mut x = Self::with_capacity(self.len());
155 for v in self.iter() {
156 match v.compute(stk, ctx, opt, doc).await {
157 Ok(v) => x.push(v),
158 Err(e) => return Err(e),
159 };
160 }
161 Ok(Value::Array(x))
162 }
163
164 pub(crate) fn is_all_none_or_null(&self) -> bool {
165 self.0.iter().all(|v| v.is_none_or_null())
166 }
167
168 pub(crate) fn is_static(&self) -> bool {
170 self.iter().all(Value::is_static)
171 }
172
173 pub fn validate_computed(&self) -> Result<(), Error> {
175 self.iter().try_for_each(|v| v.validate_computed())
176 }
177}
178
179impl Display for Array {
180 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
181 let mut f = Pretty::from(f);
182 f.write_char('[')?;
183 if !self.is_empty() {
184 let indent = pretty_indent();
185 write!(f, "{}", Fmt::pretty_comma_separated(self.as_slice()))?;
186 drop(indent);
187 }
188 f.write_char(']')
189 }
190}
191
192impl ops::Add<Value> for Array {
195 type Output = Self;
196 fn add(mut self, other: Value) -> Self {
197 self.0.push(other);
198 self
199 }
200}
201
202impl ops::Add for Array {
203 type Output = Self;
204 fn add(mut self, mut other: Self) -> Self {
205 self.0.append(&mut other.0);
206 self
207 }
208}
209
210impl ops::Sub<Value> for Array {
213 type Output = Self;
214 fn sub(mut self, other: Value) -> Self {
215 if let Some(p) = self.0.iter().position(|x| *x == other) {
216 self.0.remove(p);
217 }
218 self
219 }
220}
221
222impl ops::Sub for Array {
223 type Output = Self;
224 fn sub(mut self, other: Self) -> Self {
225 for v in other.0 {
226 if let Some(p) = self.0.iter().position(|x| *x == v) {
227 self.0.remove(p);
228 }
229 }
230 self
231 }
232}
233
234pub trait Abolish<T> {
237 fn abolish<F>(&mut self, f: F)
238 where
239 F: FnMut(usize) -> bool;
240}
241
242impl<T> Abolish<T> for Vec<T> {
243 fn abolish<F>(&mut self, mut f: F)
244 where
245 F: FnMut(usize) -> bool,
246 {
247 let mut i = 0;
248 self.retain(|_| {
251 let retain = !f(i);
252 i += 1;
253 retain
254 });
255 }
256}
257
258pub(crate) trait Clump<T> {
261 fn clump(self, clump_size: usize) -> Result<T, Error>;
262}
263
264impl Clump<Array> for Array {
265 fn clump(self, clump_size: usize) -> Result<Array, Error> {
266 if clump_size < 1 {
267 return Err(Error::InvalidArguments {
268 name: "array::clump".to_string(),
269 message: "The second argument must be an integer greater than 0".to_string(),
270 });
271 }
272
273 Ok(self
274 .0
275 .chunks(clump_size)
276 .map::<Value, _>(|chunk| chunk.to_vec().into())
277 .collect::<Vec<_>>()
278 .into())
279 }
280}
281
282pub(crate) trait Combine<T> {
285 fn combine(self, other: T) -> T;
286}
287
288impl Combine<Array> for Array {
289 fn combine(self, other: Self) -> Array {
290 let mut out = Self::with_capacity(self.len().saturating_mul(other.len()));
291 for a in self.iter() {
292 for b in other.iter() {
293 out.push(vec![a.clone(), b.clone()].into());
294 }
295 }
296 out
297 }
298}
299
300pub(crate) trait Complement<T> {
303 fn complement(self, other: T) -> T;
304}
305
306impl Complement<Array> for Array {
307 fn complement(self, other: Self) -> Array {
308 let mut out = Array::new();
309 for v in self.into_iter() {
310 if !other.contains(&v) {
311 out.push(v)
312 }
313 }
314 out
315 }
316}
317
318#[allow(dead_code)]
321pub(crate) trait Concat<T> {
322 fn concat(self, other: T) -> T;
323}
324
325impl Concat<Array> for Array {
326 fn concat(mut self, mut other: Array) -> Array {
327 self.append(&mut other);
328 self
329 }
330}
331
332impl Concat<String> for String {
333 fn concat(self, other: String) -> String {
334 self + &other
335 }
336}
337
338pub(crate) trait Difference<T> {
341 fn difference(self, other: T) -> T;
342}
343
344impl Difference<Array> for Array {
345 fn difference(self, mut other: Array) -> Array {
346 let mut out = Array::new();
347 for v in self.into_iter() {
348 if let Some(pos) = other.iter().position(|w| v == *w) {
349 other.remove(pos);
350 } else {
351 out.push(v);
352 }
353 }
354 out.append(&mut other);
355 out
356 }
357}
358
359pub(crate) trait Flatten<T> {
362 fn flatten(self) -> T;
363}
364
365impl Flatten<Array> for Array {
366 fn flatten(self) -> Array {
367 let mut out = Array::new();
368 for v in self.into_iter() {
369 match v {
370 Value::Array(mut a) => out.append(&mut a),
371 _ => out.push(v),
372 }
373 }
374 out
375 }
376}
377
378pub(crate) trait Intersect<T> {
381 fn intersect(self, other: T) -> T;
382}
383
384impl Intersect<Self> for Array {
385 fn intersect(self, mut other: Self) -> Self {
386 let mut out = Self::new();
387 for v in self.0.into_iter() {
388 if let Some(pos) = other.iter().position(|w| v == *w) {
389 other.remove(pos);
390 out.push(v);
391 }
392 }
393 out
394 }
395}
396
397pub(crate) trait Matches<T> {
401 fn matches(self, compare_val: Value) -> T;
408}
409
410impl Matches<Array> for Array {
411 fn matches(self, compare_val: Value) -> Array {
412 self.iter().map(|arr_val| (arr_val == &compare_val).into()).collect::<Vec<Value>>().into()
413 }
414}
415
416pub(crate) trait Transpose<T> {
420 fn transpose(self) -> T;
452}
453
454impl Transpose<Array> for Array {
455 fn transpose(self) -> Array {
456 if self.is_empty() {
457 return self;
458 }
459 let mut transposed_vec = Vec::<Value>::with_capacity(self.len());
462 let mut iters = self
463 .iter()
464 .map(|v| {
465 if let Value::Array(arr) = v {
466 Box::new(arr.iter().cloned()) as Box<dyn ExactSizeIterator<Item = Value>>
467 } else {
468 Box::new(std::iter::once(v).cloned())
469 as Box<dyn ExactSizeIterator<Item = Value>>
470 }
471 })
472 .collect::<Vec<_>>();
473 let longest_length = iters.iter().map(|i| i.len()).max().unwrap();
476 for _ in 0..longest_length {
477 transposed_vec.push(
478 iters
479 .iter_mut()
480 .map(|i| i.next().unwrap_or(Value::None))
481 .collect::<Vec<_>>()
482 .into(),
483 );
484 }
485 transposed_vec.into()
486 }
487}
488
489pub(crate) trait Union<T> {
492 fn union(self, other: T) -> T;
493}
494
495impl Union<Self> for Array {
496 fn union(mut self, mut other: Self) -> Array {
497 self.append(&mut other);
498 self.uniq()
499 }
500}
501
502pub(crate) trait Uniq<T> {
505 fn uniq(self) -> T;
506}
507
508impl Uniq<Array> for Array {
509 fn uniq(mut self) -> Array {
510 #[allow(clippy::mutable_key_type)]
511 let mut set: HashSet<&Value> = HashSet::new();
512 let mut to_remove: Vec<usize> = Vec::new();
513 for (i, item) in self.iter().enumerate() {
514 if !set.insert(item) {
515 to_remove.push(i);
516 }
517 }
518 for i in to_remove.iter().rev() {
519 self.remove(*i);
520 }
521 self
522 }
523}
524
525pub(crate) trait Windows<T> {
528 fn windows(self, window_size: usize) -> Result<T, Error>;
529}
530
531impl Windows<Array> for Array {
532 fn windows(self, window_size: usize) -> Result<Array, Error> {
533 if window_size < 1 {
534 return Err(Error::InvalidArguments {
535 name: "array::windows".to_string(),
536 message: "The second argument must be an integer greater than 0".to_string(),
537 });
538 }
539
540 Ok(self
541 .0
542 .windows(window_size)
543 .map::<Value, _>(|chunk| chunk.to_vec().into())
544 .collect::<Vec<_>>()
545 .into())
546 }
547}