@@ -709,6 +709,148 @@ impl Json {
709
709
self . to_pretty_writer( & mut s as & mut io:: Writer ) . unwrap( ) ;
710
710
str :: from_utf8_owned( s. unwrap( ) ) . unwrap( )
711
711
}
712
+
713
+ /// If the Json value is an Object, returns the value associated with the provided key.
714
+ /// Otherwise, returns None.
715
+ pub fn find<' a>( & ' a self , key: & ~str ) -> Option <& ' a Json >{
716
+ match self {
717
+ & Object ( ref map) => map. find( key) ,
718
+ _ => None
719
+ }
720
+ }
721
+
722
+ /// Attempts to get a nested Json Object for each key in `keys`.
723
+ /// If any key is found not to exist, get_path will return None.
724
+ /// Otherwise, it will return the Json value associated with the final key.
725
+ pub fn find_path < ' a > ( & ' a self, keys: & [ & ~str] ) -> Option <& ' a Json >{
726
+ keys. iter( ) . fold( Some ( self ) , |target, key| target. map_or( None , |t| t. find( * key) ) )
727
+ }
728
+
729
+ /// If the Json value is an Object, performs a depth-first search until
730
+ /// a value associated with the provided key is found. If no value is found
731
+ /// or the Json value is not an Object, returns None.
732
+ pub fn search<' a>( & ' a self , key: & ~str ) -> Option <& ' a Json > {
733
+ match self {
734
+ & Object ( ref map) => {
735
+ match map. find( key) {
736
+ Some ( json_value) => Some ( json_value) ,
737
+ None => {
738
+ let mut value : Option < & ' a Json > = None ;
739
+ for ( _ , v ) in map. iter ( ) {
740
+ value = v. search ( key) ;
741
+ if value. is_some ( ) {
742
+ break ;
743
+ }
744
+ }
745
+ value
746
+ }
747
+ }
748
+ } ,
749
+ _ => None
750
+ }
751
+ }
752
+
753
+ /// Returns true if the Json value is an Object. Returns false otherwise.
754
+ pub fn is_object < ' a > ( & ' a self ) -> bool {
755
+ match self {
756
+ & Object ( _) => true ,
757
+ _ => false
758
+ }
759
+ }
760
+
761
+ /// If the Json value is an Object, returns the associated TreeMap.
762
+ /// Returns None otherwise.
763
+ pub fn as_object < ' a > ( & ' a self ) -> Option < & ' a Object > {
764
+ match self {
765
+ & Object ( ref map) => Some ( & * * map) ,
766
+ _ => None
767
+ }
768
+ }
769
+
770
+ /// Returns true if the Json value is a List. Returns false otherwise.
771
+ pub fn is_list < ' a > ( & ' a self ) -> bool {
772
+ match self {
773
+ & List ( _) => true ,
774
+ _ => false
775
+ }
776
+ }
777
+
778
+ /// If the Json value is a List, returns the associated vector.
779
+ /// Returns None otherwise.
780
+ pub fn as_list < ' a > ( & ' a self ) -> Option < & ' a List > {
781
+ match self {
782
+ & List ( ref list) => Some ( & * list) ,
783
+ _ => None
784
+ }
785
+ }
786
+
787
+ /// Returns true if the Json value is a String. Returns false otherwise.
788
+ pub fn is_str < ' a > ( & ' a self ) -> bool {
789
+ match self {
790
+ & String ( _) => true ,
791
+ _ => false
792
+ }
793
+ }
794
+
795
+ /// If the Json value is a String, returns the associated str.
796
+ /// Returns None otherwise.
797
+ pub fn as_str < ' a > ( & ' a self ) -> Option < & ' a str > {
798
+ match * self {
799
+ String ( ref s) => Some ( s. as_slice ( ) ) ,
800
+ _ => None
801
+ }
802
+ }
803
+
804
+ /// Returns true if the Json value is a Number. Returns false otherwise.
805
+ pub fn is_number ( & self ) -> bool {
806
+ match self {
807
+ & Number ( _) => true ,
808
+ _ => false
809
+ }
810
+ }
811
+
812
+ /// If the Json value is a Number, returns the associated f64.
813
+ /// Returns None otherwise.
814
+ pub fn as_number ( & self ) -> Option < f64 > {
815
+ match self {
816
+ & Number ( n) => Some ( n) ,
817
+ _ => None
818
+ }
819
+ }
820
+
821
+ /// Returns true if the Json value is a Boolean. Returns false otherwise.
822
+ pub fn is_boolean ( & self ) -> bool {
823
+ match self {
824
+ & Boolean ( _) => true ,
825
+ _ => false
826
+ }
827
+ }
828
+
829
+ /// If the Json value is a Boolean, returns the associated bool.
830
+ /// Returns None otherwise.
831
+ pub fn as_boolean ( & self ) -> Option < bool > {
832
+ match self {
833
+ & Boolean ( b) => Some ( b) ,
834
+ _ => None
835
+ }
836
+ }
837
+
838
+ /// Returns true if the Json value is a Null. Returns false otherwise.
839
+ pub fn is_null ( & self ) -> bool {
840
+ match self {
841
+ & Null => true ,
842
+ _ => false
843
+ }
844
+ }
845
+
846
+ /// If the Json value is a Null, returns ().
847
+ /// Returns None otherwise.
848
+ pub fn as_null ( & self ) -> Option < ( ) > {
849
+ match self {
850
+ & Null => Some ( ( ) ) ,
851
+ _ => None
852
+ }
853
+ }
712
854
}
713
855
714
856
pub struct Parser < T > {
@@ -2283,4 +2425,109 @@ mod tests {
2283
2425
check_err:: <DecodeEnum >( "{\" variant\" : \" C\" , \" fields\" : []}" ,
2284
2426
"unknown variant name" ) ;
2285
2427
}
2428
+
2429
+ #[ test]
2430
+ fn test_find( ) {
2431
+ let json_value = from_str( "{\" dog\" : \" cat\" }" ) . unwrap( ) ;
2432
+ let found_str = json_value. find( & ~"dog");
2433
+ assert!(found_str.is_some() && found_str.unwrap().as_str().unwrap() == &" cat");
2434
+ }
2435
+
2436
+ #[test]
2437
+ fn test_find_path(){
2438
+ let json_value = from_str(" { \" dog\" : { \" cat\" : { \" mouse\" : \"cheese\" } } } ").unwrap();
2439
+ let found_str = json_value.find_path(&[&~" dog", &~" cat", &~" mouse"]);
2440
+ assert!(found_str.is_some() && found_str.unwrap().as_str().unwrap() == &" cheese");
2441
+ }
2442
+
2443
+ #[test]
2444
+ fn test_search(){
2445
+ let json_value = from_str(" { \" dog\" : { \" cat\" : { \" mouse\" : \"cheese\" } } } ").unwrap();
2446
+ let found_str = json_value.search(&~" mouse").and_then(|j| j.as_str());
2447
+ assert!(found_str.is_some());
2448
+ assert!(found_str.unwrap() == &" cheese");
2449
+ }
2450
+
2451
+ #[test]
2452
+ fn test_is_object(){
2453
+ let json_value = from_str(" { } ").unwrap();
2454
+ assert!(json_value.is_object());
2455
+ }
2456
+
2457
+ #[test]
2458
+ fn test_as_object(){
2459
+ let json_value = from_str(" { } ").unwrap();
2460
+ let json_object = json_value.as_object();
2461
+ assert!(json_object.is_some());
2462
+ }
2463
+
2464
+ #[test]
2465
+ fn test_is_list(){
2466
+ let json_value = from_str(" [ 1 , 2 , 3 ] ").unwrap();
2467
+ assert!(json_value.is_list());
2468
+ }
2469
+
2470
+ #[test]
2471
+ fn test_as_list(){
2472
+ let json_value = from_str(" [ 1 , 2 , 3 ] ").unwrap();
2473
+ let json_list = json_value.as_list();
2474
+ let expected_length = 3;
2475
+ assert!(json_list.is_some() && json_list.unwrap().len() == expected_length);
2476
+ }
2477
+
2478
+ #[test]
2479
+ fn test_is_str(){
2480
+ let json_value = from_str("\" dog\" " ) . unwrap( ) ;
2481
+ assert!( json_value. is_str( ) ) ;
2482
+ }
2483
+
2484
+ #[ test]
2485
+ fn test_as_str( ) {
2486
+ let json_value = from_str( "\" dog\" " ) . unwrap( ) ;
2487
+ let json_str = json_value. as_str( ) ;
2488
+ let expected_str = & "dog" ;
2489
+ assert_eq!( json_str, Some ( expected_str) ) ;
2490
+ }
2491
+
2492
+ #[ test]
2493
+ fn test_is_number( ) {
2494
+ let json_value = from_str( "12" ) . unwrap( ) ;
2495
+ assert!( json_value. is_number( ) ) ;
2496
+ }
2497
+
2498
+ #[ test]
2499
+ fn test_as_number( ) {
2500
+ let json_value = from_str( "12" ) . unwrap( ) ;
2501
+ let json_num = json_value. as_number( ) ;
2502
+ let expected_num = 12f64 ;
2503
+ assert!( json_num. is_some( ) && json_num. unwrap( ) == expected_num) ;
2504
+ }
2505
+
2506
+ #[ test]
2507
+ fn test_is_boolean( ) {
2508
+ let json_value = from_str( "false" ) . unwrap( ) ;
2509
+ assert!( json_value. is_boolean( ) ) ;
2510
+ }
2511
+
2512
+ #[ test]
2513
+ fn test_as_boolean( ) {
2514
+ let json_value = from_str( "false" ) . unwrap( ) ;
2515
+ let json_bool = json_value. as_boolean( ) ;
2516
+ let expected_bool = false ;
2517
+ assert!( json_bool. is_some( ) && json_bool. unwrap( ) == expected_bool) ;
2518
+ }
2519
+
2520
+ #[ test]
2521
+ fn test_is_null( ) {
2522
+ let json_value = from_str( "null" ) . unwrap( ) ;
2523
+ assert!( json_value. is_null( ) ) ;
2524
+ }
2525
+
2526
+ #[ test]
2527
+ fn test_as_null( ) {
2528
+ let json_value = from_str( "null" ) . unwrap( ) ;
2529
+ let json_null = json_value. as_null( ) ;
2530
+ let expected_null = ( ) ;
2531
+ assert!( json_null. is_some( ) && json_null. unwrap( ) == expected_null) ;
2532
+ }
2286
2533
}
0 commit comments