116
116
117
117
use crate :: parser:: model:: JsonPath ;
118
118
use crate :: parser:: parser:: parse_json_path;
119
+ use crate :: path:: config:: JsonPathConfig ;
119
120
use crate :: path:: { json_path_instance, PathInstance } ;
120
121
use serde_json:: Value ;
121
122
use std:: convert:: TryInto ;
@@ -182,8 +183,12 @@ impl FromStr for JsonPathInst {
182
183
}
183
184
184
185
impl JsonPathInst {
185
- pub fn find_slice < ' a > ( & ' a self , value : & ' a Value ) -> Vec < JsonPtr < ' a , Value > > {
186
- json_path_instance ( & self . inner , value)
186
+ pub fn find_slice < ' a > (
187
+ & ' a self ,
188
+ value : & ' a Value ,
189
+ cfg : JsonPathConfig ,
190
+ ) -> Vec < JsonPtr < ' a , Value > > {
191
+ json_path_instance ( & self . inner , value, cfg)
187
192
. find ( JsonPathValue :: from_root ( value) )
188
193
. into_iter ( )
189
194
. filter ( |v| v. has_value ( ) )
@@ -224,13 +229,27 @@ impl JsonPathQuery for Box<Value> {
224
229
}
225
230
}
226
231
232
+ impl JsonPathQuery for ( Box < Value > , JsonPathConfig ) {
233
+ fn path ( self , query : & str ) -> Result < Value , String > {
234
+ let p = JsonPathInst :: from_str ( query) ?;
235
+ Ok ( JsonPathFinder :: new_with_cfg ( self . 0 , Box :: new ( p) , self . 1 ) . find ( ) )
236
+ }
237
+ }
238
+
227
239
impl JsonPathQuery for Value {
228
240
fn path ( self , query : & str ) -> Result < Value , String > {
229
241
let p = JsonPathInst :: from_str ( query) ?;
230
242
Ok ( JsonPathFinder :: new ( Box :: new ( self ) , Box :: new ( p) ) . find ( ) )
231
243
}
232
244
}
233
245
246
+ impl JsonPathQuery for ( Value , JsonPathConfig ) {
247
+ fn path ( self , query : & str ) -> Result < Value , String > {
248
+ let p = JsonPathInst :: from_str ( query) ?;
249
+ Ok ( JsonPathFinder :: new_with_cfg ( Box :: new ( self . 0 ) , Box :: new ( p) , self . 1 ) . find ( ) )
250
+ }
251
+ }
252
+
234
253
/// just to create a json path value of data
235
254
/// Example:
236
255
/// - json_path_value(&json) = `JsonPathValue::Slice(&json)`
@@ -294,6 +313,7 @@ type JsPathStr = String;
294
313
pub ( crate ) fn jsp_idx ( prefix : & str , idx : usize ) -> String {
295
314
format ! ( "{}[{}]" , prefix, idx)
296
315
}
316
+
297
317
pub ( crate ) fn jsp_obj ( prefix : & str , key : & str ) -> String {
298
318
format ! ( "{}.['{}']" , prefix, key)
299
319
}
@@ -337,7 +357,7 @@ impl<'a, Data: Clone + Debug + Default> JsonPathValue<'a, Data> {
337
357
}
338
358
339
359
impl < ' a , Data > JsonPathValue < ' a , Data > {
340
- fn only_no_value ( input : & Vec < JsonPathValue < ' a , Data > > ) -> bool {
360
+ fn only_no_value ( input : & [ JsonPathValue < ' a , Data > ] ) -> bool {
341
361
!input. is_empty ( ) && input. iter ( ) . filter ( |v| v. has_value ( ) ) . count ( ) == 0
342
362
}
343
363
fn map_vec ( data : Vec < ( & ' a Data , JsPathStr ) > ) -> Vec < JsonPathValue < ' a , Data > > {
@@ -407,12 +427,26 @@ impl<'a, Data> JsonPathValue<'a, Data> {
407
427
pub struct JsonPathFinder {
408
428
json : Box < Value > ,
409
429
path : Box < JsonPathInst > ,
430
+ cfg : JsonPathConfig ,
410
431
}
411
432
412
433
impl JsonPathFinder {
413
434
/// creates a new instance of [JsonPathFinder]
414
435
pub fn new ( json : Box < Value > , path : Box < JsonPathInst > ) -> Self {
415
- JsonPathFinder { json, path }
436
+ JsonPathFinder {
437
+ json,
438
+ path,
439
+ cfg : JsonPathConfig :: default ( ) ,
440
+ }
441
+ }
442
+
443
+ pub fn new_with_cfg ( json : Box < Value > , path : Box < JsonPathInst > , cfg : JsonPathConfig ) -> Self {
444
+ JsonPathFinder { json, path, cfg }
445
+ }
446
+
447
+ /// sets a cfg with a new one
448
+ pub fn set_cfg ( & mut self , cfg : JsonPathConfig ) {
449
+ self . cfg = cfg
416
450
}
417
451
418
452
/// updates a path with a new one
@@ -440,10 +474,15 @@ impl JsonPathFinder {
440
474
let path = Box :: new ( JsonPathInst :: from_str ( path) ?) ;
441
475
Ok ( JsonPathFinder :: new ( json, path) )
442
476
}
477
+ pub fn from_str_with_cfg ( json : & str , path : & str , cfg : JsonPathConfig ) -> Result < Self , String > {
478
+ let json = serde_json:: from_str ( json) . map_err ( |e| e. to_string ( ) ) ?;
479
+ let path = Box :: new ( JsonPathInst :: from_str ( path) ?) ;
480
+ Ok ( JsonPathFinder :: new_with_cfg ( json, path, cfg) )
481
+ }
443
482
444
483
/// creates an instance to find a json slice from the json
445
484
pub fn instance ( & self ) -> PathInstance {
446
- json_path_instance ( & self . path . inner , & self . json )
485
+ json_path_instance ( & self . path . inner , & self . json , self . cfg . clone ( ) )
447
486
}
448
487
/// finds a slice of data in the set json.
449
488
/// The result is a vector of references to the incoming structure.
@@ -494,6 +533,7 @@ impl JsonPathFinder {
494
533
495
534
#[ cfg( test) ]
496
535
mod tests {
536
+ use crate :: path:: config:: JsonPathConfig ;
497
537
use crate :: JsonPathQuery ;
498
538
use crate :: JsonPathValue :: { NoValue , Slice } ;
499
539
use crate :: { jp_v, JsonPathFinder , JsonPathInst , JsonPathValue } ;
@@ -1194,7 +1234,7 @@ mod tests {
1194
1234
let query = JsonPathInst :: from_str ( "$..book[?(@.author size 10)].title" )
1195
1235
. expect ( "the path is correct" ) ;
1196
1236
1197
- let results = query. find_slice ( & json) ;
1237
+ let results = query. find_slice ( & json, JsonPathConfig :: default ( ) ) ;
1198
1238
let v = results. first ( ) . expect ( "to get value" ) ;
1199
1239
1200
1240
// V can be implicitly converted to &Value
@@ -1257,7 +1297,7 @@ mod tests {
1257
1297
v,
1258
1298
vec![ Slice (
1259
1299
& json!( { "second" : { "active" : 1 } } ) ,
1260
- "$.['first']" . to_string( )
1300
+ "$.['first']" . to_string( ) ,
1261
1301
) ]
1262
1302
) ;
1263
1303
@@ -1271,7 +1311,7 @@ mod tests {
1271
1311
v,
1272
1312
vec![ Slice (
1273
1313
& json!( { "second" : { "active" : 1 } } ) ,
1274
- "$.['first']" . to_string( )
1314
+ "$.['first']" . to_string( ) ,
1275
1315
) ]
1276
1316
) ;
1277
1317
@@ -1285,7 +1325,7 @@ mod tests {
1285
1325
v,
1286
1326
vec![ Slice (
1287
1327
& json!( { "second" : { "active" : 1 } } ) ,
1288
- "$.['first']" . to_string( )
1328
+ "$.['first']" . to_string( ) ,
1289
1329
) ]
1290
1330
) ;
1291
1331
@@ -1299,7 +1339,7 @@ mod tests {
1299
1339
v,
1300
1340
vec![ Slice (
1301
1341
& json!( { "second" : { "active" : 1 } } ) ,
1302
- "$.['first']" . to_string( )
1342
+ "$.['first']" . to_string( ) ,
1303
1343
) ]
1304
1344
) ;
1305
1345
}
0 commit comments