Skip to content

Commit dbb9c99

Browse files
committed
rollup merge of #18544 : whataloadofwhat/json
2 parents ee5d238 + ab9a1b7 commit dbb9c99

File tree

1 file changed

+39
-17
lines changed

1 file changed

+39
-17
lines changed

src/libserialize/json.rs

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ use std::num::{FPNaN, FPInfinite};
203203
use std::str::ScalarValue;
204204
use std::string;
205205
use std::vec::Vec;
206+
use std::ops;
206207

207208
use Encodable;
208209

@@ -889,17 +890,17 @@ impl Json {
889890

890891
/// If the Json value is an Object, returns the value associated with the provided key.
891892
/// 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>{
893894
match self {
894-
&Object(ref map) => map.find(key),
895+
&Object(ref map) => map.find_with(|s| key.cmp(&s.as_slice())),
895896
_ => None
896897
}
897898
}
898899

899900
/// Attempts to get a nested Json Object for each key in `keys`.
900901
/// If any key is found not to exist, find_path will return None.
901902
/// 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>{
903904
let mut target = self;
904905
for key in keys.iter() {
905906
match target.find(*key) {
@@ -913,20 +914,19 @@ impl Json {
913914
/// If the Json value is an Object, performs a depth-first search until
914915
/// a value associated with the provided key is found. If no value is found
915916
/// 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> {
917918
match self {
918919
&Object(ref map) => {
919-
match map.find(key) {
920+
match map.find_with(|s| key.cmp(&s.as_slice())) {
920921
Some(json_value) => Some(json_value),
921922
None => {
922-
let mut value : Option<&'a Json> = None;
923923
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+
_ => ()
927927
}
928928
}
929-
value
929+
None
930930
}
931931
}
932932
},
@@ -1068,6 +1068,21 @@ impl Json {
10681068
}
10691069
}
10701070

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+
10711086
/// The output of the streaming parser.
10721087
#[deriving(PartialEq, Clone, Show)]
10731088
pub enum JsonEvent {
@@ -3089,26 +3104,33 @@ mod tests {
30893104
#[test]
30903105
fn test_find(){
30913106
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");
30943109
}
30953110

30963111
#[test]
30973112
fn test_find_path(){
30983113
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");
31023116
}
31033117

31043118
#[test]
31053119
fn test_search(){
31063120
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());
31093122
assert!(found_str.unwrap() == "cheese");
31103123
}
31113124

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+
31123134
#[test]
31133135
fn test_is_object(){
31143136
let json_value = from_str("{}").unwrap();

0 commit comments

Comments
 (0)