@@ -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
@@ -889,17 +890,17 @@ impl Json {
889
890
890
891
/// If the Json value is an Object, returns the value associated with the provided key.
891
892
/// Otherwise, returns None.
892
- pub fn find < ' a > ( & ' a self , key : & string :: String ) -> Option < & ' a Json > {
893
+ pub fn find < ' a > ( & ' a self , key : & str ) -> Option < & ' a Json > {
893
894
match self {
894
- & Object ( ref map) => map. find ( key) ,
895
+ & Object ( ref map) => map. find_with ( |s| key. cmp ( & s . as_slice ( ) ) ) ,
895
896
_ => None
896
897
}
897
898
}
898
899
899
900
/// Attempts to get a nested Json Object for each key in `keys`.
900
901
/// If any key is found not to exist, find_path will return None.
901
902
/// Otherwise, it will return the Json value associated with the final key.
902
- pub fn find_path < ' a > ( & ' a self , keys : & [ & string :: String ] ) -> Option < & ' a Json > {
903
+ pub fn find_path < ' a > ( & ' a self , keys : & [ & str ] ) -> Option < & ' a Json > {
903
904
let mut target = self ;
904
905
for key in keys. iter ( ) {
905
906
match target. find ( * key) {
@@ -913,20 +914,19 @@ impl Json {
913
914
/// If the Json value is an Object, performs a depth-first search until
914
915
/// a value associated with the provided key is found. If no value is found
915
916
/// or the Json value is not an Object, returns None.
916
- pub fn search < ' a > ( & ' a self , key : & string :: String ) -> Option < & ' a Json > {
917
+ pub fn search < ' a > ( & ' a self , key : & str ) -> Option < & ' a Json > {
917
918
match self {
918
919
& Object ( ref map) => {
919
- match map. find ( key) {
920
+ match map. find_with ( |s| key. cmp ( & s . as_slice ( ) ) ) {
920
921
Some ( json_value) => Some ( json_value) ,
921
922
None => {
922
- let mut value : Option < & ' a Json > = None ;
923
923
for ( _, v) in map. iter ( ) {
924
- value = v. search ( key) ;
925
- if value . is_some ( ) {
926
- break ;
924
+ match v. search ( key) {
925
+ x if x . is_some ( ) => return x ,
926
+ _ => ( )
927
927
}
928
928
}
929
- value
929
+ None
930
930
}
931
931
}
932
932
} ,
@@ -1068,6 +1068,21 @@ impl Json {
1068
1068
}
1069
1069
}
1070
1070
1071
+ impl < ' a > ops:: Index < & ' a str , Json > for Json {
1072
+ fn index < ' a > ( & ' a self , idx : & & str ) -> & ' a Json {
1073
+ self . find ( * idx) . unwrap ( )
1074
+ }
1075
+ }
1076
+
1077
+ impl ops:: Index < uint , Json > for Json {
1078
+ fn index < ' a > ( & ' a self , idx : & uint ) -> & ' a Json {
1079
+ match self {
1080
+ & List ( ref v) => v. index ( idx) ,
1081
+ _ => panic ! ( "can only index Json with uint if it is a list" )
1082
+ }
1083
+ }
1084
+ }
1085
+
1071
1086
/// The output of the streaming parser.
1072
1087
#[ deriving( PartialEq , Clone , Show ) ]
1073
1088
pub enum JsonEvent {
@@ -3089,26 +3104,33 @@ mod tests {
3089
3104
#[ test]
3090
3105
fn test_find ( ) {
3091
3106
let json_value = from_str ( "{\" dog\" : \" cat\" }" ) . unwrap ( ) ;
3092
- let found_str = json_value. find ( & "dog" . to_string ( ) ) ;
3093
- assert ! ( found_str. is_some ( ) && found_str . unwrap( ) . as_string( ) . unwrap( ) == "cat" ) ;
3107
+ let found_str = json_value. find ( "dog" ) ;
3108
+ assert ! ( found_str. unwrap( ) . as_string( ) . unwrap( ) == "cat" ) ;
3094
3109
}
3095
3110
3096
3111
#[ test]
3097
3112
fn test_find_path ( ) {
3098
3113
let json_value = from_str ( "{\" dog\" :{\" cat\" : {\" mouse\" : \" cheese\" }}}" ) . unwrap ( ) ;
3099
- let found_str = json_value. find_path ( & [ & "dog" . to_string ( ) ,
3100
- & "cat" . to_string ( ) , & "mouse" . to_string ( ) ] ) ;
3101
- assert ! ( found_str. is_some( ) && found_str. unwrap( ) . as_string( ) . unwrap( ) == "cheese" ) ;
3114
+ let found_str = json_value. find_path ( & [ "dog" , "cat" , "mouse" ] ) ;
3115
+ assert ! ( found_str. unwrap( ) . as_string( ) . unwrap( ) == "cheese" ) ;
3102
3116
}
3103
3117
3104
3118
#[ test]
3105
3119
fn test_search ( ) {
3106
3120
let json_value = from_str ( "{\" dog\" :{\" cat\" : {\" mouse\" : \" cheese\" }}}" ) . unwrap ( ) ;
3107
- let found_str = json_value. search ( & "mouse" . to_string ( ) ) . and_then ( |j| j. as_string ( ) ) ;
3108
- assert ! ( found_str. is_some( ) ) ;
3121
+ let found_str = json_value. search ( "mouse" ) . and_then ( |j| j. as_string ( ) ) ;
3109
3122
assert ! ( found_str. unwrap( ) == "cheese" ) ;
3110
3123
}
3111
3124
3125
+ #[ test]
3126
+ fn test_index ( ) {
3127
+ let json_value = from_str ( "{\" animals\" :[\" dog\" ,\" cat\" ,\" mouse\" ]}" ) . unwrap ( ) ;
3128
+ let ref list = json_value[ "animals" ] ;
3129
+ assert_eq ! ( list[ 0 ] . as_string( ) . unwrap( ) , "dog" ) ;
3130
+ assert_eq ! ( list[ 1 ] . as_string( ) . unwrap( ) , "cat" ) ;
3131
+ assert_eq ! ( list[ 2 ] . as_string( ) . unwrap( ) , "mouse" ) ;
3132
+ }
3133
+
3112
3134
#[ test]
3113
3135
fn test_is_object ( ) {
3114
3136
let json_value = from_str ( "{}" ) . unwrap ( ) ;
0 commit comments