@@ -20,9 +20,9 @@ use jsonb::{
2020 array_length, array_values, as_bool, as_null, as_number, as_str, build_array, build_object,
2121 compare, concat, contains, convert_to_comparable, delete_by_index, delete_by_keypath,
2222 delete_by_name, exists_all_keys, exists_any_keys, from_slice, get_by_index, get_by_keypath,
23- get_by_name, get_by_path, is_array, is_object, keypath:: parse_key_paths, object_each ,
24- object_keys, parse_value, path_exists, path_match, strip_nulls, to_bool, to_f64, to_i64 ,
25- to_pretty_string, to_serde_json, to_serde_json_object, to_str, to_string, to_u64,
23+ get_by_name, get_by_path, get_by_path_array , is_array, is_object, keypath:: parse_key_paths,
24+ object_each , object_keys, parse_value, path_exists, path_match, strip_nulls, to_bool, to_f64,
25+ to_i64 , to_pretty_string, to_serde_json, to_serde_json_object, to_str, to_string, to_u64,
2626 traverse_check_string, type_of, Error , Number , Object , Value ,
2727} ;
2828
@@ -175,6 +175,74 @@ fn test_path_exists() {
175175 }
176176}
177177
178+ #[ test]
179+ fn test_path_exists_expr ( ) {
180+ let source = r#"{"items": [
181+ {"id": 0, "name": "Andrew", "car": "Volvo"},
182+ {"id": 1, "name": "Fred", "car": "BMW"},
183+ {"id": 2, "name": "James"},
184+ {"id": 3, "name": "Ken"}
185+ ]}"# ;
186+ let paths = vec ! [
187+ (
188+ "$.items[*]?(exists($.items))" ,
189+ r#"[
190+ {"id": 0, "name": "Andrew", "car": "Volvo"},
191+ {"id": 1, "name": "Fred", "car": "BMW"},
192+ {"id": 2, "name": "James"},
193+ {"id": 3, "name": "Ken"}
194+ ]"# ,
195+ ) ,
196+ (
197+ "$.items[*]?(exists(@.car))" ,
198+ r#"[
199+ {"id": 0, "name": "Andrew", "car": "Volvo"},
200+ {"id": 1, "name": "Fred", "car": "BMW"}
201+ ]"# ,
202+ ) ,
203+ (
204+ r#"$.items[*]?(exists(@.car?(@ == "Volvo")))"# ,
205+ r#"[
206+ {"id": 0, "name": "Andrew", "car": "Volvo"}
207+ ]"# ,
208+ ) ,
209+ (
210+ r#"$.items[*]?(exists(@.car) && @.id >= 1)"# ,
211+ r#"[
212+ {"id": 1, "name": "Fred", "car": "BMW"}
213+ ]"# ,
214+ ) ,
215+ (
216+ r#"$ ? (exists(@.items[*]?(exists(@.car))))"# ,
217+ r#"[{"items": [
218+ {"id": 0, "name": "Andrew", "car": "Volvo"},
219+ {"id": 1, "name": "Fred", "car": "BMW"},
220+ {"id": 2, "name": "James"},
221+ {"id": 3, "name": "Ken"}
222+ ]}]"# ,
223+ ) ,
224+ (
225+ r#"$ ? (exists(@.items[*]?(exists(@.car) && @.id == 5)))"# ,
226+ r#"[]"# ,
227+ ) ,
228+ ] ;
229+
230+ let mut buf: Vec < u8 > = Vec :: new ( ) ;
231+ let value = parse_value ( source. as_bytes ( ) ) . unwrap ( ) ;
232+ value. write_to_vec ( & mut buf) ;
233+
234+ for ( path, expected) in paths {
235+ let mut out_buf: Vec < u8 > = Vec :: new ( ) ;
236+ let mut out_offsets: Vec < u64 > = Vec :: new ( ) ;
237+ let json_path = parse_json_path ( path. as_bytes ( ) ) . unwrap ( ) ;
238+
239+ get_by_path_array ( & buf, json_path, & mut out_buf, & mut out_offsets) ;
240+ let expected_buf = parse_value ( expected. as_bytes ( ) ) . unwrap ( ) . to_vec ( ) ;
241+
242+ assert_eq ! ( out_buf, expected_buf) ;
243+ }
244+ }
245+
178246#[ test]
179247fn test_get_by_path ( ) {
180248 let source = r#"{"name":"Fred","phones":[{"type":"home","number":3720453},{"type":"work","number":5062051}],"car_no":123,"测试\"\uD83D\uDC8E":"ab"}"# ;
0 commit comments