topo 0.9.4

Reified activation records and scoped thread-locals for UI runtimes.

topo creates a hierarchy of nested scopes represented as stable identifiers referring to the function callgraph.

Each scope in this hierarchy has a unique and deterministic [crate::Id] describing that environment and the path taken to arrive at its stack frame. These identifiers are derived from the path taken through the callgraph to the current location, and are stable across repeated invocations of the same execution paths.

By running the same topologically-nested functions in a loop, we can observe changes to the structure over time. The moxie crate uses these identifiers and environments to create persistent trees for rendering human interfaces.

Making functions nested within the call topology

Define a topologically-nested function with the topo::nested attribute:

#![feature(track_caller)]

#[topo::nested]
fn basic_topo() -> topo::Id { topo::Id::current() }

#[topo::nested]
fn tier_two() -> topo::Id { basic_topo() }

// each of these functions will be run in separately identified
// contexts as the source locations for their calls are different
let first = basic_topo();
let second = basic_topo();
assert_ne!(first, second);

let third = tier_two();
let fourth = tier_two();
assert_ne!(third, fourth);
assert_ne!(first, third);
assert_ne!(first, fourth);
assert_ne!(second, fourth);