#linked-list #stack-frame #json-path #call-stack #recursion #chained #along

no-std stackstack

A singly linked list intended to be chained along stack frames

4 releases (2 breaking)

0.3.0 Jul 12, 2024
0.2.0 Jul 10, 2024
0.1.1 Jul 10, 2024
0.1.0 Jul 10, 2024

#646 in Rust patterns

Download history 298/week @ 2024-07-22 209/week @ 2024-07-29 325/week @ 2024-08-05 569/week @ 2024-08-12 705/week @ 2024-08-19 576/week @ 2024-08-26 877/week @ 2024-09-02 537/week @ 2024-09-09 525/week @ 2024-09-16 623/week @ 2024-09-23 780/week @ 2024-09-30 384/week @ 2024-10-07 260/week @ 2024-10-14 271/week @ 2024-10-21 249/week @ 2024-10-28 393/week @ 2024-11-04

1,198 downloads per month
Used in clap-doc

MIT/Apache

19KB
286 lines

A singly linked list intended to be chained along (program) stack frames.

This is useful for visitors and recursive functions.

Example: a JSON visitor


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")
]}

No runtime deps