Crates.io | stackstack |
lib.rs | stackstack |
version | 0.3.0 |
source | src |
created_at | 2024-07-10 01:10:51.119205 |
updated_at | 2024-07-12 16:38:18.54688 |
description | A singly linked list intended to be chained along stack frames. |
homepage | https://crates.io/crates/stackstack |
repository | https://github.com/aatifsyed/stackstack |
max_upload_size | |
id | 1297676 |
size | 18,897 |
A singly linked list intended to be chained along (program) stack frames.
This is useful for visitors and recursive functions.
enum Path<'a> {
Key(&'a str),
Index(usize),
}
impl std::fmt::Display for Path<'_> { ... }
/// Recursively visit JSON strings, recording their path and contents
fn collect_strs<'a>(
v: &mut Vec<(String, &'a str)>,
path: stackstack::Stack<Path>,
// ^^^^^^^^^^^ shared across recursive calls
json: &'a serde_json::Value,
) {
match json {
Value::String(it) => v.push((itertools::join(&path, "."), it)),
// iterate the path to the current node ~~^
Value::Array(arr) => {
for (ix, child) in arr.iter().enumerate() {
collect_strs(v, path.pushed(Path::Index(ix)), child)
// ^~~ recurse with an appended path
}
}
Value::Object(obj) => {
for (k, child) in obj {
collect_strs(v, path.pushed(Path::Key(k)), child)
// ^~~ the new node is allocated on
// the current (program) stack frame
}
},
_ => {}
}
}
let mut v = vec![];
let json = json!({
"mary": {
"had": [
{"a": "little lamb"},
{"two": "yaks"}
]
}
});
collect_strs(&mut v, Stack::new(), &json);
assert_eq! { v, [
("mary.had.0.a".into(), "little lamb"),
("mary.had.1.two".into(), "yaks")
]}