Skip to content

Instantly share code, notes, and snippets.

@zslayton
Created December 9, 2013 03:58
Show Gist options
  • Save zslayton/7867213 to your computer and use it in GitHub Desktop.
Save zslayton/7867213 to your computer and use it in GitHub Desktop.
extern mod extra;
use extra::treemap::TreeMap;
use extra::json::{Json,Object,from_str};
/*
fn find_nested_string(&self, key_iterator: I) -> Result<V, NestedSearchError>;
fn find_nested_number(&self, key_iterator: I) -> Result<V, NestedSearchError>;
fn find_nested_boolean(&self, key_iterator: I) -> Result<V, NestedSearchError>;
fn find_nested_list(&self, key_iterator: I) -> Result<V, NestedSearchError>;
fn find_nested_object(&self, key_iterator: I) -> Result<V, NestedSearchError>;
fn find_nested_null(&self, key_iterator: I) -> Result<V, NestedSearchError>;
*/
enum NestedSearchError {
NoSuchAncestor(~str),
NoSuchKey,
TypeMismatch,
AncestorTypeMismatch(~str),
EmptyKeyIterator
}
trait NestedMap <'a, K, V, I : Iterator<&'a K>> {
fn find_nested(&self, key_iterator: I) -> Result<V, NestedSearchError>;
}
fn end_of_keys(value: Option<Json>) -> Result<Json, NestedSearchError>{
match value {
Some(json_value) => {
Ok(json_value)
},
None => {
Err(NoSuchKey)
}
}
}
fn handle_nested_value <'a, I: Iterator<&'a ~str>> (last_key: &~str, key_iterator: I, value: Option<Json>) -> Result<Json, NestedSearchError> {
match key_iterator.next() {
Some(key) => { // Keys remain
match value {
Some(json_value) => {
match json_value {
Object(ref map) => {
map.find_nested(key_iterator)
},
_ => {
Err(AncestorTypeMismatch(last_key.to_owned()))
}
}
},
None => {
Err(NoSuchAncestor(last_key.to_owned()))
}
}
},
None => end_of_keys(value)
}
}
impl <'a, I : Iterator<&'a ~str>> NestedMap <'a, ~str, Json, I> for TreeMap <~str, Json> {
fn find_nested(&self, key_iterator: I) -> Result<Json, NestedSearchError>{
match key_iterator.next() {
Some(key) => {
let value = self.find(key);
handle_nested_value(key, key_iterator, value);
},
None => {
Err(EmptyKeyIterator)
}
}
}
}
fn main(){
//let obj = Object(~TreeMap::<~str, Json>::new());
let obj = from_str("{\"dog\":{\"cat\": {\"mouse\" : 5}}}").unwrap();
match obj {
Object(ref map) => {
let key_list = [~"dog", ~"cat", ~"mouse"];
match map.find_nested(key_list.iter()) {
Ok(json_value) => println(~"Got it!: " + json_value.to_pretty_str()),
Err(NoSuchAncestor(field_name)) => println!("Missing ancestor field '{:s}'", field_name),
Err(AncestorTypeMismatch(field_name)) => println!("Ancestor field '{:s}' was not an object.", field_name),
Err(NoSuchKey) => println!("The requested field doesn't exist."),
Err(_) => println!("Other error.")
}
},
_ => println("Error. :(")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment