I ran through the standard JSON library of Rust http://doc.rust-lang.org/serialize/json/ and couldn't figure out what represents a node in it. In Java it's JsonNode. What's it in Rust? For example, how can I pass an argument of the type JsonNode in Rust?
1 Answer
Rust's "DOM" for JSON is defined by Json enum. For example, this JSON object:
{ "array": [1, 2, 3], "submap": { "bool": true, "string": "abcde" } }
is represented by this expression in Rust:
macro_rules! tree_map {
($($k:expr -> $v:expr),*) => ({
let mut r = ::std::collections::TreeMap::new();
$(r.insert($k, $v);)*
r
})
}
let data = json::Object(tree_map! {
"array".to_string() -> json::List(vec![json::U64(1), json::U64(2), json::U64(3)]),
"submap".to_string() -> json::Object(tree_map! {
"bool".to_string() -> json::Boolean(true),
"string".to_string() -> json::String("abcde".to_string())
})
});
(try it here)
I've used custom map construction macro because unfortunately Rust standard library does not provide one (yet, I hope).
Json is just a regular enum, so you have to use pattern matching to extract values from it. Object contains an instance of TreeMap, so then you have to use its methods to inspect object structure:
if let json::Object(ref m) = data {
if let Some(value) = m.find_with(|k| "submap".cmp(k)) {
println!("Found value at 'submap' key: {}", value);
} else {
println!("'submap' key does not exist");
}
} else {
println!("data is not an object")
}
Update
Apparently, Json provides a lot of convenience methods, including find(), which will return Option<&Json> if the target is an Object which has corresponding key:
if let Some(value) = data.find("submap") {
println!("Found value at 'submap' key: {}", value);
} else {
println!("'submap' key does not exist or data is not an Object");
}
Thanks @ChrisMorgan for the finding.
6 Comments
json.find(&String)Json has methods of its own! Only it seems that it is &str, not &String.