surrealdb_expr/val/value/
cut.rs1use crate::expr::part::{Next, Part};
2use crate::val::Value;
3
4impl Value {
5 pub fn cut(&mut self, path: &[Part]) {
7 if let Some(p) = path.first() {
8 match self {
10 Value::Object(v) => match p {
12 Part::Field(f) => match path.len() {
13 1 => {
14 v.remove(f);
15 }
16 _ => {
17 if let Some(v) = v.get_mut(f) {
18 v.cut(path.next())
19 }
20 }
21 },
22 Part::All => match path.len() {
23 1 => {
24 v.clear();
25 }
26 _ => {
27 let path = path.next();
28 v.iter_mut().for_each(|(_, v)| v.cut(path));
29 }
30 },
31 x => {
32 if let Some(i) = x.as_old_index() {
33 match path.len() {
34 1 => {
35 v.remove(&i.to_string());
36 }
37 _ => {
38 if let Some(v) = v.get_mut(&i.to_string()) {
39 v.cut(path.next())
40 }
41 }
42 }
43 }
44 }
45 },
46 Value::Array(v) => match p {
48 Part::All => match path.len() {
49 1 => {
50 v.clear();
51 }
52 _ => {
53 let path = path.next();
54 v.iter_mut().for_each(|v| v.cut(path));
55 }
56 },
57 Part::First => match path.len() {
58 1 => {
59 if !v.is_empty() {
60 let i = 0;
61 v.remove(i);
62 }
63 }
64 _ => {
65 if let Some(v) = v.first_mut() {
66 v.cut(path.next())
67 }
68 }
69 },
70 Part::Last => match path.len() {
71 1 => {
72 if !v.is_empty() {
73 let i = v.len() - 1;
74 v.remove(i);
75 }
76 }
77 _ => {
78 if let Some(v) = v.last_mut() {
79 v.cut(path.next())
80 }
81 }
82 },
83 x => {
84 if let Some(i) = x.as_old_index() {
85 match path.len() {
86 1 => {
87 if v.len() > i {
88 v.remove(i);
89 }
90 }
91 _ => {
92 if let Some(v) = v.get_mut(i) {
93 v.cut(path.next())
94 }
95 }
96 }
97 } else {
98 v.iter_mut().for_each(|v| v.cut(path));
99 }
100 }
101 },
102 _ => (),
104 }
105 }
106 }
107}
108
109#[cfg(test)]
110mod tests {
111
112 use crate::expr::idiom::Idiom;
113 use crate::syn;
114
115 macro_rules! parse_val {
116 ($input:expr) => {
117 crate::val::convert_public_value_to_internal(syn::value($input).unwrap())
118 };
119 }
120
121 #[tokio::test]
122 async fn cut_none() {
123 let idi: Idiom = Idiom::default();
124 let mut val = parse_val!("{ test: { other: null, something: 123 } }");
125 let res = parse_val!("{ test: { other: null, something: 123 } }");
126 val.cut(&idi);
127 assert_eq!(res, val);
128 }
129
130 #[tokio::test]
131 async fn cut_reset() {
132 let idi: Idiom = syn::idiom("test").unwrap().into();
133 let mut val = parse_val!("{ test: { other: null, something: 123 } }");
134 let res = parse_val!("{ }");
135 val.cut(&idi);
136 assert_eq!(res, val);
137 }
138
139 #[tokio::test]
140 async fn cut_basic() {
141 let idi: Idiom = syn::idiom("test.something").unwrap().into();
142 let mut val = parse_val!("{ test: { other: null, something: 123 } }");
143 let res = parse_val!("{ test: { other: null } }");
144 val.cut(&idi);
145 assert_eq!(res, val);
146 }
147
148 #[tokio::test]
149 async fn cut_wrong() {
150 let idi: Idiom = syn::idiom("test.something.wrong").unwrap().into();
151 let mut val = parse_val!("{ test: { other: null, something: 123 } }");
152 let res = parse_val!("{ test: { other: null, something: 123 } }");
153 val.cut(&idi);
154 assert_eq!(res, val);
155 }
156
157 #[tokio::test]
158 async fn cut_other() {
159 let idi: Idiom = syn::idiom("test.other.something").unwrap().into();
160 let mut val = parse_val!("{ test: { other: null, something: 123 } }");
161 let res = parse_val!("{ test: { other: null, something: 123 } }");
162 val.cut(&idi);
163 assert_eq!(res, val);
164 }
165
166 #[tokio::test]
167 async fn cut_array() {
168 let idi: Idiom = syn::idiom("test.something[1]").unwrap().into();
169 let mut val = parse_val!("{ test: { something: [123, 456, 789] } }");
170 let res = parse_val!("{ test: { something: [123, 789] } }");
171 val.cut(&idi);
172 assert_eq!(res, val);
173 }
174
175 #[tokio::test]
176 async fn cut_array_field() {
177 let idi: Idiom = syn::idiom("test.something[1].age").unwrap().into();
178 let mut val =
179 parse_val!("{ test: { something: [{ name: 'A', age: 34 }, { name: 'B', age: 36 }] } }");
180 let res = parse_val!("{ test: { something: [{ name: 'A', age: 34 }, { name: 'B' }] } }");
181 val.cut(&idi);
182 assert_eq!(res, val);
183 }
184
185 #[tokio::test]
186 async fn cut_array_fields() {
187 let idi: Idiom = syn::idiom("test.something[*].age").unwrap().into();
188 let mut val =
189 parse_val!("{ test: { something: [{ name: 'A', age: 34 }, { name: 'B', age: 36 }] } }");
190 let res = parse_val!("{ test: { something: [{ name: 'A' }, { name: 'B' }] } }");
191 val.cut(&idi);
192 assert_eq!(res, val);
193 }
194
195 #[tokio::test]
196 async fn cut_array_fields_flat() {
197 let idi: Idiom = syn::idiom("test.something.age").unwrap().into();
198 let mut val =
199 parse_val!("{ test: { something: [{ name: 'A', age: 34 }, { name: 'B', age: 36 }] } }");
200 let res = parse_val!("{ test: { something: [{ name: 'A' }, { name: 'B' }] } }");
201 val.cut(&idi);
202 assert_eq!(res, val);
203 }
204}