surrealdb_core/sql/value/
put.rs1use crate::sql::part::Next;
2use crate::sql::part::Part;
3use crate::sql::value::Value;
4
5impl Value {
6 pub fn put(&mut self, path: &[Part], val: Value) {
8 match path.first() {
9 Some(p) => match self {
11 Value::Object(v) => match p {
13 Part::Graph(g) => match v.get_mut(g.to_raw().as_str()) {
14 Some(v) if v.is_some() => v.put(path.next(), val),
15 _ => {
16 let mut obj = Value::base();
17 obj.put(path.next(), val);
18 v.insert(g.to_raw(), obj);
19 }
20 },
21 Part::Field(f) => match v.get_mut(f.to_raw().as_str()) {
22 Some(v) if v.is_some() => v.put(path.next(), val),
23 _ => {
24 let mut obj = Value::base();
25 obj.put(path.next(), val);
26 v.insert(f.to_raw(), obj);
27 }
28 },
29 Part::Index(i) => match v.get_mut(&i.to_string()) {
30 Some(v) if v.is_some() => v.put(path.next(), val),
31 _ => {
32 let mut obj = Value::base();
33 obj.put(path.next(), val);
34 v.insert(i.to_string(), obj);
35 }
36 },
37 Part::All => {
38 let path = path.next();
39 v.iter_mut().for_each(|(_, v)| v.put(path, val.clone()));
40 }
41 _ => (),
42 },
43 Value::Array(v) => match p {
45 Part::All => {
46 let path = path.next();
47 v.iter_mut().for_each(|v| v.put(path, val.clone()));
48 }
49 Part::First => {
50 if let Some(v) = v.first_mut() {
51 v.put(path.next(), val)
52 }
53 }
54 Part::Last => {
55 if let Some(v) = v.last_mut() {
56 v.put(path.next(), val)
57 }
58 }
59 Part::Index(i) => {
60 if let Some(v) = v.get_mut(i.to_usize()) {
61 v.put(path.next(), val)
62 }
63 }
64 _ => {
65 v.iter_mut().for_each(|v| v.put(path, val.clone()));
66 }
67 },
68 Value::Null => {
70 *self = Value::base();
71 self.put(path, val)
72 }
73 Value::None => {
75 *self = Value::base();
76 self.put(path, val)
77 }
78 _ => (),
80 },
81 None => {
83 *self = val;
84 }
85 }
86 }
87}
88
89#[cfg(test)]
90mod tests {
91
92 use super::*;
93 use crate::sql::idiom::Idiom;
94 use crate::syn::Parse;
95
96 #[tokio::test]
97 async fn put_none() {
98 let idi = Idiom::default();
99 let mut val = Value::parse("{ test: { other: null, something: 123 } }");
100 let res = Value::parse("999");
101 val.put(&idi, Value::from(999));
102 assert_eq!(res, val);
103 }
104
105 #[tokio::test]
106 async fn put_empty() {
107 let idi = Idiom::parse("test");
108 let mut val = Value::None;
109 let res = Value::parse("{ test: 999 }");
110 val.put(&idi, Value::from(999));
111 assert_eq!(res, val);
112 }
113
114 #[tokio::test]
115 async fn put_blank() {
116 let idi = Idiom::parse("test.something");
117 let mut val = Value::None;
118 let res = Value::parse("{ test: { something: 999 } }");
119 val.put(&idi, Value::from(999));
120 assert_eq!(res, val);
121 }
122
123 #[tokio::test]
124 async fn put_reput() {
125 let idi = Idiom::parse("test");
126 let mut val = Value::parse("{ test: { other: null, something: 123 } }");
127 let res = Value::parse("{ test: 999 }");
128 val.put(&idi, Value::from(999));
129 assert_eq!(res, val);
130 }
131
132 #[tokio::test]
133 async fn put_basic() {
134 let idi = Idiom::parse("test.something");
135 let mut val = Value::parse("{ test: { other: null, something: 123 } }");
136 let res = Value::parse("{ test: { other: null, something: 999 } }");
137 val.put(&idi, Value::from(999));
138 assert_eq!(res, val);
139 }
140
141 #[tokio::test]
142 async fn put_allow() {
143 let idi = Idiom::parse("test.something.allow");
144 let mut val = Value::parse("{ test: { other: null } }");
145 let res = Value::parse("{ test: { other: null, something: { allow: 999 } } }");
146 val.put(&idi, Value::from(999));
147 assert_eq!(res, val);
148 }
149
150 #[tokio::test]
151 async fn put_wrong() {
152 let idi = Idiom::parse("test.something.wrong");
153 let mut val = Value::parse("{ test: { other: null, something: 123 } }");
154 let res = Value::parse("{ test: { other: null, something: 123 } }");
155 val.put(&idi, Value::from(999));
156 assert_eq!(res, val);
157 }
158
159 #[tokio::test]
160 async fn put_other() {
161 let idi = Idiom::parse("test.other.something");
162 let mut val = Value::parse("{ test: { other: null, something: 123 } }");
163 let res = Value::parse("{ test: { other: { something: 999 }, something: 123 } }");
164 val.put(&idi, Value::from(999));
165 assert_eq!(res, val);
166 }
167
168 #[tokio::test]
169 async fn put_array() {
170 let idi = Idiom::parse("test.something[1]");
171 let mut val = Value::parse("{ test: { something: [123, 456, 789] } }");
172 let res = Value::parse("{ test: { something: [123, 999, 789] } }");
173 val.put(&idi, Value::from(999));
174 assert_eq!(res, val);
175 }
176
177 #[tokio::test]
178 async fn put_array_field() {
179 let idi = Idiom::parse("test.something[1].age");
180 let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
181 let res = Value::parse("{ test: { something: [{ age: 34 }, { age: 21 }] } }");
182 val.put(&idi, Value::from(21));
183 assert_eq!(res, val);
184 }
185
186 #[tokio::test]
187 async fn put_array_fields() {
188 let idi = Idiom::parse("test.something[*].age");
189 let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
190 let res = Value::parse("{ test: { something: [{ age: 21 }, { age: 21 }] } }");
191 val.put(&idi, Value::from(21));
192 assert_eq!(res, val);
193 }
194
195 #[tokio::test]
196 async fn put_array_fields_flat() {
197 let idi = Idiom::parse("test.something.age");
198 let mut val = Value::parse("{ test: { something: [{ age: 34 }, { age: 36 }] } }");
199 let res = Value::parse("{ test: { something: [{ age: 21 }, { age: 21 }] } }");
200 val.put(&idi, Value::from(21));
201 assert_eq!(res, val);
202 }
203}