Implement SQL Array as a newtype tuple struct

This commit is contained in:
Tobie Morgan Hitchcock 2022-05-04 17:14:40 +01:00
parent 3ee1ddb5b1
commit 143da56728
20 changed files with 166 additions and 193 deletions

View file

@ -45,7 +45,7 @@ impl Array {
txn: &Transaction,
chn: &Sender<(Option<Thing>, Value)>,
) -> Result<(), Error> {
for v in self.value.into_iter() {
for v in self {
if ctx.is_ok() {
match v {
Value::Array(v) => v.process(ctx, opt, stm, txn, chn).await?,

View file

@ -45,7 +45,7 @@ impl Array {
txn: &Transaction,
ite: &mut Iterator,
) -> Result<(), Error> {
for v in self.value.into_iter() {
for v in self.into_iter() {
if ctx.is_ok() {
match v {
Value::Array(v) => v.iterate(ctx, opt, txn, ite).await?,

View file

@ -169,7 +169,7 @@ impl Iterator {
// Set the value at the path
match val {
Value::Array(v) => {
for val in v.value {
for val in v {
// Make a copy of object
let mut obj = obj.clone();
// Set the value at the path
@ -215,11 +215,11 @@ impl Iterator {
// Get the value at the path
let val = obj.pick(&group.group);
// Set the value at the path
arr.value.push(val);
arr.push(val);
}
// Add to grouped collection
match grp.get_mut(&arr) {
Some(v) => v.value.push(obj),
Some(v) => v.push(obj),
None => {
grp.insert(arr, Array::from(obj));
}

View file

@ -30,13 +30,13 @@ impl<'a> Document<'a> {
let mut o = Array::with_capacity(ix.cols.len());
for i in ix.cols.iter() {
let v = i.compute(ctx, opt, txn, Some(&self.current)).await?;
o.value.push(v);
o.push(v);
}
// Calculate new values
let mut n = Array::with_capacity(ix.cols.len());
for i in ix.cols.iter() {
let v = i.compute(ctx, opt, txn, Some(&self.current)).await?;
n.value.push(v);
n.push(v);
}
// Clone transaction
let run = txn.clone();

View file

@ -11,7 +11,7 @@ use crate::sql::value::Value;
pub fn concat(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
match args.remove(0) {
Value::Array(v) => match args.remove(0) {
Value::Array(w) => Ok(v.value.concat(w.value).into()),
Value::Array(w) => Ok(v.concat(w).into()),
_ => Ok(Value::None),
},
_ => Ok(Value::None),
@ -21,7 +21,7 @@ pub fn concat(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
pub fn combine(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
match args.remove(0) {
Value::Array(v) => match args.remove(0) {
Value::Array(w) => Ok(v.value.combine(w.value).into()),
Value::Array(w) => Ok(v.combine(w).into()),
_ => Ok(Value::None),
},
_ => Ok(Value::None),
@ -31,7 +31,7 @@ pub fn combine(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
pub fn difference(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
match args.remove(0) {
Value::Array(v) => match args.remove(0) {
Value::Array(w) => Ok(v.value.difference(w.value).into()),
Value::Array(w) => Ok(v.difference(w).into()),
_ => Ok(Value::None),
},
_ => Ok(Value::None),
@ -40,7 +40,7 @@ pub fn difference(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
pub fn distinct(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
match args.remove(0) {
Value::Array(v) => Ok(v.value.uniq().into()),
Value::Array(v) => Ok(v.uniq().into()),
_ => Ok(Value::None),
}
}
@ -48,7 +48,7 @@ pub fn distinct(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
pub fn intersect(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
match args.remove(0) {
Value::Array(v) => match args.remove(0) {
Value::Array(w) => Ok(v.value.intersect(w.value).into()),
Value::Array(w) => Ok(v.intersect(w).into()),
_ => Ok(Value::None),
},
_ => Ok(Value::None),
@ -57,7 +57,7 @@ pub fn intersect(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
pub fn len(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
match args.remove(0) {
Value::Array(v) => Ok(v.value.len().into()),
Value::Array(v) => Ok(v.len().into()),
_ => Ok(Value::None),
}
}
@ -65,7 +65,7 @@ pub fn len(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
pub fn union(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
match args.remove(0) {
Value::Array(v) => match args.remove(0) {
Value::Array(w) => Ok(v.value.union(w.value).into()),
Value::Array(w) => Ok(v.union(w).into()),
_ => Ok(Value::None),
},
_ => Ok(Value::None),

View file

@ -5,7 +5,7 @@ use crate::sql::value::Value;
pub fn count(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
match args.len() {
1 => match args.remove(0) {
Value::Array(v) => Ok(v.value.iter().filter(|v| v.is_truthy()).count().into()),
Value::Array(v) => Ok(v.iter().filter(|v| v.is_truthy()).count().into()),
v => match v.is_truthy() {
true => Ok(1.into()),
false => Ok(0.into()),

View file

@ -20,11 +20,11 @@ pub fn r#enum(_: &Runtime, mut args: Vec<Value>) -> Result<Value, Error> {
match args.len() {
0 => Ok(Value::None),
1 => match args.remove(0) {
Value::Array(mut v) => match v.value.len() {
Value::Array(mut v) => match v.len() {
0 => Ok(Value::None),
n => {
let i = rand::thread_rng().gen_range(0..n);
Ok(v.value.remove(i))
Ok(v.remove(i))
}
},
v => Ok(v),

View file

@ -12,120 +12,113 @@ use crate::sql::value::{value, Value};
use nom::character::complete::char;
use nom::combinator::opt;
use nom::multi::separated_list0;
use serde::ser::SerializeStruct;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops;
use std::ops::Deref;
use std::ops::DerefMut;
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize)]
pub struct Array {
pub value: Vec<Value>,
}
pub struct Array(pub Vec<Value>);
impl From<Value> for Array {
fn from(v: Value) -> Self {
Array {
value: vec![v],
}
Array(vec![v])
}
}
impl From<Vec<Value>> for Array {
fn from(v: Vec<Value>) -> Self {
Array {
value: v,
}
Array(v)
}
}
impl From<Vec<i32>> for Array {
fn from(v: Vec<i32>) -> Self {
Array {
value: v.into_iter().map(|x| x.into()).collect(),
}
Array(v.into_iter().map(|x| x.into()).collect())
}
}
impl From<Vec<String>> for Array {
fn from(v: Vec<String>) -> Self {
Array {
value: v.into_iter().map(|x| x.into()).collect(),
}
Array(v.into_iter().map(|x| x.into()).collect())
}
}
impl From<Vec<Vec<Value>>> for Array {
fn from(v: Vec<Vec<Value>>) -> Self {
Array {
value: v.into_iter().map(|x| x.into()).collect(),
}
Array(v.into_iter().map(|x| x.into()).collect())
}
}
impl<'a> From<Vec<&str>> for Array {
fn from(v: Vec<&str>) -> Self {
Array {
value: v.into_iter().map(Value::from).collect(),
}
Array(v.into_iter().map(Value::from).collect())
}
}
impl From<Vec<Operation>> for Array {
fn from(v: Vec<Operation>) -> Self {
Array {
value: v.into_iter().map(Value::from).collect(),
Array(v.into_iter().map(Value::from).collect())
}
}
impl Deref for Array {
type Target = Vec<Value>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Array {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl IntoIterator for Array {
type Item = Value;
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl Array {
pub fn new() -> Self {
Array {
value: Vec::default(),
}
Array(Vec::default())
}
pub fn with_capacity(len: usize) -> Self {
Array {
value: Vec::with_capacity(len),
}
}
pub fn len(&self) -> usize {
self.value.len()
}
pub fn is_empty(&self) -> bool {
self.value.is_empty()
Array(Vec::with_capacity(len))
}
pub fn as_ints(self) -> Vec<i64> {
self.value.into_iter().map(|v| v.as_int()).collect()
self.0.into_iter().map(|v| v.as_int()).collect()
}
pub fn as_floats(self) -> Vec<f64> {
self.value.into_iter().map(|v| v.as_float()).collect()
self.0.into_iter().map(|v| v.as_float()).collect()
}
pub fn as_numbers(self) -> Vec<Number> {
self.value.into_iter().map(|v| v.as_number()).collect()
self.0.into_iter().map(|v| v.as_number()).collect()
}
pub fn as_strands(self) -> Vec<Strand> {
self.value.into_iter().map(|v| v.as_strand()).collect()
self.0.into_iter().map(|v| v.as_strand()).collect()
}
pub fn as_point(mut self) -> [f64; 2] {
match self.len() {
0 => [0.0, 0.0],
1 => [self.value.remove(0).as_float(), 0.0],
_ => [self.value.remove(0).as_float(), self.value.remove(0).as_float()],
1 => [self.0.remove(0).as_float(), 0.0],
_ => [self.0.remove(0).as_float(), self.0.remove(0).as_float()],
}
}
pub fn to_operations(&self) -> Result<Vec<Operation>, Error> {
self.value
.iter()
self.iter()
.map(|v| match v {
Value::Object(v) => v.to_operation(),
_ => Err(Error::InvalidPatch {
@ -145,25 +138,19 @@ impl Array {
doc: Option<&Value>,
) -> Result<Value, Error> {
let mut x = Vec::new();
for v in &self.value {
for v in self.iter() {
match v.compute(ctx, opt, txn, doc).await {
Ok(v) => x.push(v),
Err(e) => return Err(e),
};
}
Ok(Value::Array(Array {
value: x,
}))
Ok(Value::Array(Array(x)))
}
}
impl fmt::Display for Array {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"[{}]",
self.value.iter().map(|ref v| format!("{}", v)).collect::<Vec<_>>().join(", ")
)
write!(f, "[{}]", self.iter().map(|ref v| format!("{}", v)).collect::<Vec<_>>().join(", "))
}
}
@ -173,11 +160,9 @@ impl Serialize for Array {
S: serde::Serializer,
{
if serializer.is_human_readable() {
serializer.serialize_some(&self.value)
serializer.serialize_some(&self.0)
} else {
let mut val = serializer.serialize_struct("Array", 1)?;
val.serialize_field("value", &self.value)?;
val.end()
serializer.serialize_newtype_struct("Array", &self.0)
}
}
}
@ -187,8 +172,8 @@ impl Serialize for Array {
impl ops::Add<Value> for Array {
type Output = Self;
fn add(mut self, other: Value) -> Self {
if !self.value.iter().any(|x| *x == other) {
self.value.push(other)
if !self.0.iter().any(|x| *x == other) {
self.0.push(other)
}
self
}
@ -197,9 +182,9 @@ impl ops::Add<Value> for Array {
impl ops::Add for Array {
type Output = Self;
fn add(mut self, other: Self) -> Self {
for v in other.value {
if !self.value.iter().any(|x| *x == v) {
self.value.push(v)
for v in other.0 {
if !self.0.iter().any(|x| *x == v) {
self.0.push(v)
}
}
self
@ -211,8 +196,8 @@ impl ops::Add for Array {
impl ops::Sub<Value> for Array {
type Output = Self;
fn sub(mut self, other: Value) -> Self {
if let Some(p) = self.value.iter().position(|x| *x == other) {
self.value.remove(p);
if let Some(p) = self.0.iter().position(|x| *x == other) {
self.0.remove(p);
}
self
}
@ -221,9 +206,9 @@ impl ops::Sub<Value> for Array {
impl ops::Sub for Array {
type Output = Self;
fn sub(mut self, other: Self) -> Self {
for v in other.value {
if let Some(p) = self.value.iter().position(|x| *x == v) {
self.value.remove(p);
for v in other.0 {
if let Some(p) = self.0.iter().position(|x| *x == v) {
self.0.remove(p);
}
}
self
@ -265,15 +250,15 @@ impl<T> Abolish<T> for Vec<T> {
// ------------------------------
pub trait Combine<T> {
fn combine(self, other: Vec<T>) -> Vec<Vec<T>>;
fn combine(self, other: T) -> T;
}
impl<T: PartialEq + Clone> Combine<T> for Vec<T> {
fn combine(self, other: Vec<T>) -> Vec<Vec<T>> {
let mut out = Vec::new();
impl Combine<Array> for Array {
fn combine(self, other: Array) -> Array {
let mut out = Array::new();
for a in self.iter() {
for b in other.iter() {
out.push(vec![a.clone(), b.clone()]);
out.push(vec![a.clone(), b.clone()].into());
}
}
out
@ -283,11 +268,11 @@ impl<T: PartialEq + Clone> Combine<T> for Vec<T> {
// ------------------------------
pub trait Concat<T> {
fn concat(self, other: Vec<T>) -> Vec<T>;
fn concat(self, other: T) -> T;
}
impl<T: PartialEq> Concat<T> for Vec<T> {
fn concat(mut self, mut other: Vec<T>) -> Vec<T> {
impl Concat<Array> for Array {
fn concat(mut self, mut other: Array) -> Array {
self.append(&mut other);
self
}
@ -296,12 +281,12 @@ impl<T: PartialEq> Concat<T> for Vec<T> {
// ------------------------------
pub trait Difference<T> {
fn difference(self, other: Vec<T>) -> Vec<T>;
fn difference(self, other: T) -> T;
}
impl<T: PartialEq> Difference<T> for Vec<T> {
fn difference(self, other: Vec<T>) -> Vec<T> {
let mut out = Vec::new();
impl Difference<Array> for Array {
fn difference(self, other: Array) -> Array {
let mut out = Array::new();
let mut other: Vec<_> = other.into_iter().collect();
for a in self.into_iter() {
if let Some(pos) = other.iter().position(|b| a == *b) {
@ -318,14 +303,14 @@ impl<T: PartialEq> Difference<T> for Vec<T> {
// ------------------------------
pub trait Intersect<T> {
fn intersect(self, other: Vec<T>) -> Vec<T>;
fn intersect(self, other: T) -> T;
}
impl<T: PartialEq> Intersect<T> for Vec<T> {
fn intersect(self, other: Vec<T>) -> Vec<T> {
let mut out = Vec::new();
impl Intersect<Array> for Array {
fn intersect(self, other: Array) -> Array {
let mut out = Array::new();
let mut other: Vec<_> = other.into_iter().collect();
for a in self.into_iter() {
for a in self.0.into_iter() {
if let Some(pos) = other.iter().position(|b| a == *b) {
out.push(a);
other.remove(pos);
@ -338,11 +323,11 @@ impl<T: PartialEq> Intersect<T> for Vec<T> {
// ------------------------------
pub trait Union<T> {
fn union(self, other: Vec<T>) -> Vec<T>;
fn union(self, other: T) -> T;
}
impl<T: PartialEq> Union<T> for Vec<T> {
fn union(mut self, mut other: Vec<T>) -> Vec<T> {
impl Union<Array> for Array {
fn union(mut self, mut other: Array) -> Array {
self.append(&mut other);
self.uniq()
}
@ -351,11 +336,11 @@ impl<T: PartialEq> Union<T> for Vec<T> {
// ------------------------------
pub trait Uniq<T> {
fn uniq(self) -> Vec<T>;
fn uniq(self) -> T;
}
impl<T: PartialEq> Uniq<T> for Vec<T> {
fn uniq(mut self) -> Vec<T> {
impl Uniq<Array> for Array {
fn uniq(mut self) -> Array {
for x in (0..self.len()).rev() {
for y in (x + 1..self.len()).rev() {
if self[x] == self[y] {
@ -377,12 +362,7 @@ pub fn array(i: &str) -> IResult<&str, Array> {
let (i, _) = opt(char(','))(i)?;
let (i, _) = mightbespace(i)?;
let (i, _) = char(']')(i)?;
Ok((
i,
Array {
value: v,
},
))
Ok((i, Array(v)))
}
fn item(i: &str) -> IResult<&str, Value> {
@ -402,7 +382,7 @@ mod tests {
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("[1, 2, 3]", format!("{}", out));
assert_eq!(out.value.len(), 3);
assert_eq!(out.0.len(), 3);
}
#[test]
@ -412,7 +392,7 @@ mod tests {
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("[1, 2, 3]", format!("{}", out));
assert_eq!(out.value.len(), 3);
assert_eq!(out.0.len(), 3);
}
#[test]
@ -422,6 +402,6 @@ mod tests {
assert!(res.is_ok());
let out = res.unwrap().1;
assert_eq!("[1, 2, 3 + 1]", format!("{}", out));
assert_eq!(out.value.len(), 3);
assert_eq!(out.0.len(), 3);
}
}

View file

@ -55,7 +55,7 @@ impl InsertStatement {
Data::SingleExpression(v) => {
let v = v.compute(ctx, opt, txn, doc).await?;
match v {
Value::Array(v) => v.value.into_iter().for_each(|v| i.prepare(v)),
Value::Array(v) => v.into_iter().for_each(|v| i.prepare(v)),
Value::Object(_) => i.prepare(v),
v => {
return Err(Error::InsertStatement {

View file

@ -91,7 +91,7 @@ impl Subquery {
// Process subquery
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
1 => Ok(v.remove(0)),
_ => Ok(v.into()),
},
v => Ok(v),
@ -112,7 +112,7 @@ impl Subquery {
// Process subquery
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
1 => Ok(v.remove(0)),
_ => Ok(v.into()),
},
v => Ok(v),
@ -133,7 +133,7 @@ impl Subquery {
// Process subquery
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
1 => Ok(v.remove(0)),
_ => Ok(v.into()),
},
v => Ok(v),
@ -154,7 +154,7 @@ impl Subquery {
// Process subquery
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
1 => Ok(v.remove(0)),
_ => Ok(v.into()),
},
v => Ok(v),
@ -175,7 +175,7 @@ impl Subquery {
// Process subquery
match Arc::clone(v).compute(&ctx, &opt, txn, doc).await? {
Value::Array(mut v) => match v.len() {
1 => Ok(v.value.remove(0)),
1 => Ok(v.remove(0)),
_ => Ok(v.into()),
},
v => Ok(v),

View file

@ -27,7 +27,7 @@ impl Value {
// Current path part is an array
(Value::Array(a), Value::Array(b)) => match p {
Part::All => {
for (a, b) in a.value.iter().zip(b.value.iter()) {
for (a, b) in a.iter().zip(b.iter()) {
match a.compare(b, path.next(), collate, numeric) {
Some(Ordering::Equal) => continue,
None => continue,
@ -40,28 +40,26 @@ impl Value {
_ => Some(Ordering::Equal),
}
}
Part::First => match (a.value.first(), b.value.first()) {
Part::First => match (a.first(), b.first()) {
(Some(a), Some(b)) => a.compare(b, path.next(), collate, numeric),
(Some(_), None) => Some(Ordering::Greater),
(None, Some(_)) => Some(Ordering::Less),
(_, _) => Some(Ordering::Equal),
},
Part::Last => match (a.value.first(), b.value.first()) {
Part::Last => match (a.first(), b.first()) {
(Some(a), Some(b)) => a.compare(b, path.next(), collate, numeric),
(Some(_), None) => Some(Ordering::Greater),
(None, Some(_)) => Some(Ordering::Less),
(_, _) => Some(Ordering::Equal),
},
Part::Index(i) => {
match (a.value.get(i.to_usize()), b.value.get(i.to_usize())) {
Part::Index(i) => match (a.get(i.to_usize()), b.get(i.to_usize())) {
(Some(a), Some(b)) => a.compare(b, path.next(), collate, numeric),
(Some(_), None) => Some(Ordering::Greater),
(None, Some(_)) => Some(Ordering::Less),
(_, _) => Some(Ordering::Equal),
}
}
},
_ => {
for (a, b) in a.value.iter().zip(b.value.iter()) {
for (a, b) in a.iter().zip(b.iter()) {
match a.compare(b, path, collate, numeric) {
Some(Ordering::Equal) => continue,
None => continue,

View file

@ -41,48 +41,50 @@ impl Value {
Value::Array(v) => match p {
Part::All => match path.len() {
1 => {
v.value.clear();
v.clear();
Ok(())
}
_ => {
let path = path.next();
let futs = v.value.iter_mut().map(|v| v.del(ctx, opt, txn, path));
let futs = v.iter_mut().map(|v| v.del(ctx, opt, txn, path));
try_join_all(futs).await?;
Ok(())
}
},
Part::First => match path.len() {
1 => {
if v.value.len().gt(&0) {
v.value.remove(0);
if v.len().gt(&0) {
let i = 0;
v.remove(i);
}
Ok(())
}
_ => match v.value.first_mut() {
_ => match v.first_mut() {
Some(v) => v.del(ctx, opt, txn, path.next()).await,
None => Ok(()),
},
},
Part::Last => match path.len() {
1 => {
if v.value.len().gt(&0) {
v.value.remove(v.value.len() - 1);
if v.len().gt(&0) {
let i = v.len() - 1;
v.remove(i);
}
Ok(())
}
_ => match v.value.last_mut() {
_ => match v.last_mut() {
Some(v) => v.del(ctx, opt, txn, path.next()).await,
None => Ok(()),
},
},
Part::Index(i) => match path.len() {
1 => {
if v.value.len().gt(&i.to_usize()) {
v.value.remove(i.to_usize());
if v.len().gt(&i.to_usize()) {
v.remove(i.to_usize());
}
Ok(())
}
_ => match v.value.get_mut(i.to_usize()) {
_ => match v.get_mut(i.to_usize()) {
Some(v) => v.del(ctx, opt, txn, path.next()).await,
None => Ok(()),
},
@ -90,17 +92,17 @@ impl Value {
Part::Where(w) => match path.len() {
1 => {
let mut m = HashMap::new();
for (i, v) in v.value.iter().enumerate() {
for (i, v) in v.iter().enumerate() {
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
m.insert(i, ());
};
}
v.value.abolish(|i| m.contains_key(&i));
v.abolish(|i| m.contains_key(&i));
Ok(())
}
_ => {
let path = path.next();
for v in &mut v.value {
for v in v.iter_mut() {
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
v.del(ctx, opt, txn, path).await?;
}
@ -110,11 +112,11 @@ impl Value {
},
_ => match path.len() {
1 => {
v.value.clear();
v.clear();
Ok(())
}
_ => {
let futs = v.value.iter_mut().map(|v| v.del(ctx, opt, txn, path));
let futs = v.iter_mut().map(|v| v.del(ctx, opt, txn, path));
try_join_all(futs).await?;
Ok(())
}

View file

@ -37,7 +37,7 @@ impl Value {
let mut n = 0;
while n < min(a.len(), b.len()) {
let path = path.clone().push(n.into());
ops.append(&mut a.value[n].diff(&b.value[n], path));
ops.append(&mut a[n].diff(&b[n], path));
n += 1;
}
while n < b.len() {
@ -45,7 +45,7 @@ impl Value {
ops.push(Operation {
op: Op::Add,
path: path.clone().push(n.into()),
value: b.value[n].clone(),
value: b[n].clone(),
})
}
n += 1;

View file

@ -23,25 +23,23 @@ impl Value {
// Current path part is an array
Value::Array(v) => match p {
Part::All => v
.value
.iter()
.enumerate()
.flat_map(|(i, v)| v._each(path.next(), prev.clone().push(Part::from(i))))
.collect::<Vec<_>>(),
Part::First => match v.value.first() {
Part::First => match v.first() {
Some(v) => v._each(path.next(), prev.push(p.clone())),
None => vec![],
},
Part::Last => match v.value.last() {
Part::Last => match v.last() {
Some(v) => v._each(path.next(), prev.push(p.clone())),
None => vec![],
},
Part::Index(i) => match v.value.get(i.to_usize()) {
Part::Index(i) => match v.get(i.to_usize()) {
Some(v) => v._each(path.next(), prev.push(p.clone())),
None => vec![],
},
_ => v
.value
.iter()
.enumerate()
.flat_map(|(i, v)| v._each(path.next(), prev.clone().push(Part::from(i))))

View file

@ -15,7 +15,6 @@ impl Value {
.collect::<Vec<_>>(),
// Current path part is an array
Value::Array(v) => v
.value
.iter()
.enumerate()
.flat_map(|(i, v)| v._every(prev.clone().push(Part::from(i))))

View file

@ -37,25 +37,25 @@ impl Value {
Value::Array(v) => match p {
Part::All => {
let path = path.next();
let futs = v.value.iter().map(|v| v.get(ctx, opt, txn, path));
let futs = v.iter().map(|v| v.get(ctx, opt, txn, path));
try_join_all(futs).await.map(|v| v.into())
}
Part::First => match v.value.first() {
Part::First => match v.first() {
Some(v) => v.get(ctx, opt, txn, path.next()).await,
None => Ok(Value::None),
},
Part::Last => match v.value.last() {
Part::Last => match v.last() {
Some(v) => v.get(ctx, opt, txn, path.next()).await,
None => Ok(Value::None),
},
Part::Index(i) => match v.value.get(i.to_usize()) {
Part::Index(i) => match v.get(i.to_usize()) {
Some(v) => v.get(ctx, opt, txn, path.next()).await,
None => Ok(Value::None),
},
Part::Where(w) => {
let path = path.next();
let mut a = Vec::new();
for v in &v.value {
for v in v.iter() {
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
a.push(v.get(ctx, opt, txn, path).await?)
}
@ -63,7 +63,7 @@ impl Value {
Ok(a.into())
}
_ => {
let futs = v.value.iter().map(|v| v.get(ctx, opt, txn, path));
let futs = v.iter().map(|v| v.get(ctx, opt, txn, path));
try_join_all(futs).await.map(|v| v.into())
}
},

View file

@ -18,22 +18,20 @@ impl Value {
},
// Current path part is an array
Value::Array(v) => match p {
Part::All => {
v.value.iter().map(|v| v.pick(path.next())).collect::<Vec<_>>().into()
}
Part::First => match v.value.first() {
Part::All => v.iter().map(|v| v.pick(path.next())).collect::<Vec<_>>().into(),
Part::First => match v.first() {
Some(v) => v.pick(path.next()),
None => Value::None,
},
Part::Last => match v.value.last() {
Part::Last => match v.last() {
Some(v) => v.pick(path.next()),
None => Value::None,
},
Part::Index(i) => match v.value.get(i.to_usize()) {
Part::Index(i) => match v.get(i.to_usize()) {
Some(v) => v.pick(path.next()),
None => Value::None,
},
_ => v.value.iter().map(|v| v.pick(path)).collect::<Vec<_>>().into(),
_ => v.iter().map(|v| v.pick(path)).collect::<Vec<_>>().into(),
},
// Ignore everything else
_ => Value::None,

View file

@ -39,26 +39,25 @@ impl Value {
Value::Array(v) => match p {
Part::All => {
let path = path.next();
let futs =
v.value.iter_mut().map(|v| v.set(ctx, opt, txn, path, val.clone()));
let futs = v.iter_mut().map(|v| v.set(ctx, opt, txn, path, val.clone()));
try_join_all(futs).await?;
Ok(())
}
Part::First => match v.value.first_mut() {
Part::First => match v.first_mut() {
Some(v) => v.set(ctx, opt, txn, path.next(), val).await,
None => Ok(()),
},
Part::Last => match v.value.last_mut() {
Part::Last => match v.last_mut() {
Some(v) => v.set(ctx, opt, txn, path.next(), val).await,
None => Ok(()),
},
Part::Index(i) => match v.value.get_mut(i.to_usize()) {
Part::Index(i) => match v.get_mut(i.to_usize()) {
Some(v) => v.set(ctx, opt, txn, path.next(), val).await,
None => Ok(()),
},
Part::Where(w) => {
let path = path.next();
for v in &mut v.value {
for v in v.iter_mut() {
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
v.set(ctx, opt, txn, path, val.clone()).await?;
}
@ -66,8 +65,7 @@ impl Value {
Ok(())
}
_ => {
let futs =
v.value.iter_mut().map(|v| v.set(ctx, opt, txn, path, val.clone()));
let futs = v.iter_mut().map(|v| v.set(ctx, opt, txn, path, val.clone()));
try_join_all(futs).await?;
Ok(())
}

View file

@ -3,7 +3,7 @@ use crate::sql::value::Value;
impl Value {
pub fn single(&self) -> &Self {
match self {
Value::Array(v) => match v.value.first() {
Value::Array(v) => match v.first() {
None => &Value::None,
Some(v) => v,
},

View file

@ -498,7 +498,7 @@ impl Value {
Value::False => false,
Value::Thing(_) => true,
Value::Geometry(_) => true,
Value::Array(v) => !v.value.is_empty(),
Value::Array(v) => !v.is_empty(),
Value::Object(v) => !v.is_empty(),
Value::Strand(v) => !v.value.is_empty() && v.value.to_ascii_lowercase() != "false",
Value::Number(v) => v.is_truthy(),
@ -831,14 +831,14 @@ impl Value {
pub fn all_equal(&self, other: &Value) -> bool {
match self {
Value::Array(v) => v.value.iter().all(|v| v.equal(other)),
Value::Array(v) => v.iter().all(|v| v.equal(other)),
_ => self.equal(other),
}
}
pub fn any_equal(&self, other: &Value) -> bool {
match self {
Value::Array(v) => v.value.iter().any(|v| v.equal(other)),
Value::Array(v) => v.iter().any(|v| v.equal(other)),
_ => self.equal(other),
}
}
@ -855,21 +855,21 @@ impl Value {
pub fn all_fuzzy(&self, other: &Value) -> bool {
match self {
Value::Array(v) => v.value.iter().all(|v| v.fuzzy(other)),
Value::Array(v) => v.iter().all(|v| v.fuzzy(other)),
_ => self.fuzzy(other),
}
}
pub fn any_fuzzy(&self, other: &Value) -> bool {
match self {
Value::Array(v) => v.value.iter().any(|v| v.fuzzy(other)),
Value::Array(v) => v.iter().any(|v| v.fuzzy(other)),
_ => self.fuzzy(other),
}
}
pub fn contains(&self, other: &Value) -> bool {
match self {
Value::Array(v) => v.value.iter().any(|v| v.equal(other)),
Value::Array(v) => v.iter().any(|v| v.equal(other)),
Value::Strand(v) => match other {
Value::Strand(w) => v.value.contains(w.as_str()),
_ => v.value.contains(&other.to_strand().as_str()),
@ -884,8 +884,8 @@ impl Value {
pub fn contains_all(&self, other: &Value) -> bool {
match other {
Value::Array(v) => v.value.iter().all(|v| match self {
Value::Array(w) => w.value.iter().any(|w| v.equal(w)),
Value::Array(v) => v.iter().all(|v| match self {
Value::Array(w) => w.iter().any(|w| v.equal(w)),
Value::Geometry(_) => self.contains(v),
_ => false,
}),
@ -895,8 +895,8 @@ impl Value {
pub fn contains_any(&self, other: &Value) -> bool {
match other {
Value::Array(v) => v.value.iter().any(|v| match self {
Value::Array(w) => w.value.iter().any(|w| v.equal(w)),
Value::Array(v) => v.iter().any(|v| match self {
Value::Array(w) => w.iter().any(|w| v.equal(w)),
Value::Geometry(_) => self.contains(v),
_ => false,
}),