surrealdb_expr/val/value/
inc.rs1use anyhow::Result;
2
3use crate::expr::part::Part;
4use crate::val::{Number, TryAdd, Value};
5
6impl Value {
7 pub fn inc(&mut self, path: &[Part], val: Value) -> Result<()> {
9 match self.pick(path) {
10 Value::Array(v) => match val {
11 Value::Array(x) => self.put(path, Value::from(v.concat(x))),
12 x => self.put(path, Value::from(v.with_push(x))),
13 },
14 Value::None => match val {
15 Value::Number(x) => self.put(path, Value::Number(Number::Int(0) + x)),
16 Value::Array(x) => self.put(path, Value::from(x)),
17 x => self.put(path, Value::from(vec![x])),
18 },
19 v => {
20 let result = v.try_add(val)?;
21 self.put(path, result);
22 }
23 }
24 Ok(())
25 }
26}
27
28#[cfg(test)]
29mod tests {
30
31 use super::*;
32 use crate::expr::idiom::Idiom;
33 use crate::syn;
34
35 macro_rules! parse_val {
36 ($input:expr) => {
37 crate::val::convert_public_value_to_internal(syn::value($input).unwrap())
38 };
39 }
40
41 #[tokio::test]
42 async fn increment_none() {
43 let idi: Idiom = syn::idiom("other").unwrap().into();
44 let mut val = parse_val!("{ test: 100 }");
45 let res = parse_val!("{ test: 100, other: +10 }");
46 val.inc(&idi, Value::from(10)).unwrap();
47 assert_eq!(res, val);
48 }
49
50 #[tokio::test]
51 async fn increment_number() {
52 let idi: Idiom = syn::idiom("test").unwrap().into();
53 let mut val = parse_val!("{ test: 100 }");
54 let res = parse_val!("{ test: 110 }");
55 val.inc(&idi, Value::from(10)).unwrap();
56 assert_eq!(res, val);
57 }
58
59 #[tokio::test]
60 async fn increment_object_number_errors() {
61 let idi: Idiom = syn::idiom("test").unwrap().into();
62 let mut val = parse_val!("{ test: { a: 1 } }");
63 assert!(val.inc(&idi, Value::from(10)).is_err());
64 }
65
66 #[tokio::test]
67 async fn increment_array_number() {
68 let idi: Idiom = syn::idiom("test[1]").unwrap().into();
69 let mut val = parse_val!("{ test: [100, 200, 300] }");
70 let res = parse_val!("{ test: [100, 210, 300] }");
71 val.inc(&idi, Value::from(10)).unwrap();
72 assert_eq!(res, val);
73 }
74
75 #[tokio::test]
76 async fn increment_array_value() {
77 let idi: Idiom = syn::idiom("test").unwrap().into();
78 let mut val = parse_val!("{ test: [100, 200, 300] }");
79 let res = parse_val!("{ test: [100, 200, 300, 200] }");
80 val.inc(&idi, Value::from(200)).unwrap();
81 assert_eq!(res, val);
82 }
83
84 #[tokio::test]
85 async fn increment_array_array() {
86 let idi: Idiom = syn::idiom("test").unwrap().into();
87 let mut val = parse_val!("{ test: [100, 200, 300] }");
88 let res = parse_val!("{ test: [100, 200, 300, 100, 300, 400, 500] }");
89 val.inc(&idi, parse_val!("[100, 300, 400, 500]")).unwrap();
90 assert_eq!(res, val);
91 }
92}