Skip to content

Instantly share code, notes, and snippets.

@timmyjose
Created June 26, 2018 19:14
Show Gist options
  • Save timmyjose/ced86257cc6f9391c2bab7aec740017f to your computer and use it in GitHub Desktop.
Save timmyjose/ced86257cc6f9391c2bab7aec740017f to your computer and use it in GitHub Desktop.
use std::string;
enum JsonObject {
Number(i32),
String(string::String),
Array(Vec<JsonObject>),
Object(Vec<KeyVal>),
}
use JsonObject::*;
struct KeyVal {
key: &'static str,
val: JsonObject,
}
impl KeyVal {
fn new(key: &'static str, val: JsonObject) -> Self {
KeyVal { key: key, val: val }
}
}
fn main() {
// test data
let obj = JsonObject::Object(vec![
KeyVal::new(
"a",
JsonObject::Object(vec![
KeyVal::new("b", JsonObject::Number(3)),
KeyVal::new(
"c",
JsonObject::Array(vec![
JsonObject::Object(vec![KeyVal::new("d", JsonObject::Number(0))]),
JsonObject::String("e".to_string()),
JsonObject::String("f".to_string()),
JsonObject::String("g".to_string()),
JsonObject::String("h".to_string()),
JsonObject::String("i".to_string()),
JsonObject::Object(vec![KeyVal::new("x", JsonObject::Number(2))]),
JsonObject::String("j".to_string()),
JsonObject::String("k".to_string()),
JsonObject::String("l".to_string()),
JsonObject::String("m".to_string()),
JsonObject::String("n".to_string()),
JsonObject::Object(vec![KeyVal::new("y", JsonObject::Number(99))]),
JsonObject::Object(vec![KeyVal::new("z", JsonObject::Number(101))]),
JsonObject::String("o".to_string()),
JsonObject::String("p".to_string()),
]),
),
]),
),
KeyVal::new("f", JsonObject::String("hello".to_string())),
KeyVal::new(
"test",
JsonObject::Object(vec![
KeyVal::new("age", JsonObject::Number(42)),
KeyVal::new(
"name",
JsonObject::Object(vec![
KeyVal::new("lastname", JsonObject::String("Bourne".to_string())),
KeyVal::new("firstname", JsonObject::String("Jason".to_string())),
]),
),
KeyVal::new(
"cipher",
JsonObject::Array(vec![
JsonObject::Number(100),
JsonObject::Number(200),
JsonObject::Number(300),
JsonObject::Number(400),
JsonObject::Number(500),
]),
),
]),
),
]);
let paths = flatten_json_object(&obj);
for path in paths {
println!("{:?}", path);
}
}
fn flatten_json_object(obj: &JsonObject) -> Vec<Vec<string::String>> {
let mut v = Vec::new();
flatten_helper(obj, &mut string::String::new(), &mut v);
v
}
fn flatten_helper(
obj: &JsonObject,
curr_path: &mut string::String,
v: &mut Vec<Vec<string::String>>,
) {
match obj {
Object(ref kvs) => for kv in kvs.iter() {
let key_len = kv.key.len();
curr_path.push_str(kv.key.clone());
curr_path.push('.');
flatten_helper(&kv.val, curr_path, v);
for _ in 0..key_len + 1 {
curr_path.pop();
}
},
Number(n) => {
v.push(vec![curr_path.clone(), n.to_string()]);
}
String(ref s) => {
v.push(vec![curr_path.clone(), s.clone()]);
}
Array(ref objs) => for (i, val) in objs.iter().enumerate() {
curr_path.pop();
curr_path.push_str("[");
let idx = i.to_string();
let idx_len = idx.len();
curr_path.push_str(&idx);
curr_path.push_str("]");
curr_path.push('.');
flatten_helper(&val, curr_path, v);
for _ in 0..idx_len + 2 {
curr_path.pop();
}
},
}
}
Sample test output:
*******************
bash-3.2$ !!
cargo run
Compiling jsontree v0.1.0 (file:///Users/z0ltan/Code/Projects/jsontree)
Finished dev [unoptimized + debuginfo] target(s) in 0.57s
Running `target/debug/jsontree`
["a.b.", "3"]
["a.c[0].d.", "0"]
["a.c[1].", "e"]
["a.c[2].", "f"]
["a.c[3].", "g"]
["a.c[4].", "h"]
["a.c[5].", "i"]
["a.c[6].x.", "2"]
["a.c[7].", "j"]
["a.c[8].", "k"]
["a.c[9].", "l"]
["a.c[10].", "m"]
["a.c[11].", "n"]
["a.c[12].y.", "99"]
["a.c[13].z.", "101"]
["a.c[14].", "o"]
["a.c[15].", "p"]
["f.", "hello"]
["test.age.", "42"]
["test.name.lastname.", "Bourne"]
["test.name.firstname.", "Jason"]
["test.cipher[0].", "100"]
["test.cipher[1].", "200"]
["test.cipher[2].", "300"]
["test.cipher[3].", "400"]
["test.cipher[4].", "500"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment