@@ -203,6 +203,7 @@ use std::num::{FPNaN, FPInfinite};
203
203
use std:: str:: ScalarValue ;
204
204
use std:: string;
205
205
use std:: vec:: Vec ;
206
+ use std:: ops;
206
207
207
208
use Encodable ;
208
209
@@ -884,17 +885,17 @@ impl Json {
884
885
885
886
/// If the Json value is an Object, returns the value associated with the provided key.
886
887
/// Otherwise, returns None.
887
- pub fn find < ' a > ( & ' a self , key : & string :: String ) -> Option < & ' a Json > {
888
+ pub fn find < ' a > ( & ' a self , key : & str ) -> Option < & ' a Json > {
888
889
match self {
889
- & Object ( ref map) => map. find ( key) ,
890
+ & Object ( ref map) => map. find_with ( |s| key. cmp ( & s . as_slice ( ) ) ) ,
890
891
_ => None
891
892
}
892
893
}
893
894
894
895
/// Attempts to get a nested Json Object for each key in `keys`.
895
896
/// If any key is found not to exist, find_path will return None.
896
897
/// Otherwise, it will return the Json value associated with the final key.
897
- pub fn find_path < ' a > ( & ' a self , keys : & [ & string :: String ] ) -> Option < & ' a Json > {
898
+ pub fn find_path < ' a > ( & ' a self , keys : & [ & str ] ) -> Option < & ' a Json > {
898
899
let mut target = self ;
899
900
for key in keys. iter ( ) {
900
901
match target. find ( * key) {
@@ -908,20 +909,19 @@ impl Json {
908
909
/// If the Json value is an Object, performs a depth-first search until
909
910
/// a value associated with the provided key is found. If no value is found
910
911
/// or the Json value is not an Object, returns None.
911
- pub fn search < ' a > ( & ' a self , key : & string :: String ) -> Option < & ' a Json > {
912
+ pub fn search < ' a > ( & ' a self , key : & str ) -> Option < & ' a Json > {
912
913
match self {
913
914
& Object ( ref map) => {
914
- match map. find ( key) {
915
+ match map. find_with ( |s| key. cmp ( & s . as_slice ( ) ) ) {
915
916
Some ( json_value) => Some ( json_value) ,
916
917
None => {
917
- let mut value : Option < & ' a Json > = None ;
918
918
for ( _, v) in map. iter ( ) {
919
- value = v. search ( key) ;
920
- if value . is_some ( ) {
921
- break ;
919
+ match v. search ( key) {
920
+ x if x . is_some ( ) => return x ,
921
+ _ => ( )
922
922
}
923
923
}
924
- value
924
+ None
925
925
}
926
926
}
927
927
} ,
@@ -1063,6 +1063,21 @@ impl Json {
1063
1063
}
1064
1064
}
1065
1065
1066
+ impl < ' a > ops:: Index < & ' a str , Json > for Json {
1067
+ fn index < ' a > ( & ' a self , idx : & & str ) -> & ' a Json {
1068
+ self . find ( * idx) . unwrap ( )
1069
+ }
1070
+ }
1071
+
1072
+ impl ops:: Index < uint , Json > for Json {
1073
+ fn index < ' a > ( & ' a self , idx : & uint ) -> & ' a Json {
1074
+ match self {
1075
+ & List ( ref v) => v. index ( idx) ,
1076
+ _ => panic ! ( "can only index Json with uint if it is a list" )
1077
+ }
1078
+ }
1079
+ }
1080
+
1066
1081
/// The output of the streaming parser.
1067
1082
#[ deriving( PartialEq , Clone , Show ) ]
1068
1083
pub enum JsonEvent {
@@ -3055,26 +3070,33 @@ mod tests {
3055
3070
#[ test]
3056
3071
fn test_find ( ) {
3057
3072
let json_value = from_str ( "{\" dog\" : \" cat\" }" ) . unwrap ( ) ;
3058
- let found_str = json_value. find ( & "dog" . to_string ( ) ) ;
3059
- assert ! ( found_str. is_some ( ) && found_str . unwrap( ) . as_string( ) . unwrap( ) == "cat" ) ;
3073
+ let found_str = json_value. find ( "dog" ) ;
3074
+ assert ! ( found_str. unwrap( ) . as_string( ) . unwrap( ) == "cat" ) ;
3060
3075
}
3061
3076
3062
3077
#[ test]
3063
3078
fn test_find_path ( ) {
3064
3079
let json_value = from_str ( "{\" dog\" :{\" cat\" : {\" mouse\" : \" cheese\" }}}" ) . unwrap ( ) ;
3065
- let found_str = json_value. find_path ( & [ & "dog" . to_string ( ) ,
3066
- & "cat" . to_string ( ) , & "mouse" . to_string ( ) ] ) ;
3067
- assert ! ( found_str. is_some( ) && found_str. unwrap( ) . as_string( ) . unwrap( ) == "cheese" ) ;
3080
+ let found_str = json_value. find_path ( & [ "dog" , "cat" , "mouse" ] ) ;
3081
+ assert ! ( found_str. unwrap( ) . as_string( ) . unwrap( ) == "cheese" ) ;
3068
3082
}
3069
3083
3070
3084
#[ test]
3071
3085
fn test_search ( ) {
3072
3086
let json_value = from_str ( "{\" dog\" :{\" cat\" : {\" mouse\" : \" cheese\" }}}" ) . unwrap ( ) ;
3073
- let found_str = json_value. search ( & "mouse" . to_string ( ) ) . and_then ( |j| j. as_string ( ) ) ;
3074
- assert ! ( found_str. is_some( ) ) ;
3087
+ let found_str = json_value. search ( "mouse" ) . and_then ( |j| j. as_string ( ) ) ;
3075
3088
assert ! ( found_str. unwrap( ) == "cheese" ) ;
3076
3089
}
3077
3090
3091
+ #[ test]
3092
+ fn test_index ( ) {
3093
+ let json_value = from_str ( "{\" animals\" :[\" dog\" ,\" cat\" ,\" mouse\" ]}" ) . unwrap ( ) ;
3094
+ let ref list = json_value[ "animals" ] ;
3095
+ assert_eq ! ( list[ 0 ] . as_string( ) . unwrap( ) , "dog" ) ;
3096
+ assert_eq ! ( list[ 1 ] . as_string( ) . unwrap( ) , "cat" ) ;
3097
+ assert_eq ! ( list[ 2 ] . as_string( ) . unwrap( ) , "mouse" ) ;
3098
+ }
3099
+
3078
3100
#[ test]
3079
3101
fn test_is_object ( ) {
3080
3102
let json_value = from_str ( "{}" ) . unwrap ( ) ;
0 commit comments