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