Convert Rc<RefCell<T>> and Arc<Mutex<T>> pointer graphs into a flat,
inspectable, serializable form, and back.
Pointer-shaped data (trees with shared subtrees, DAGs, cyclic graphs) is awkward to serialize, log, or transform: walking it naively either duplicates shared nodes or loops forever on cycles. This crate gives you a small, non-invasive API to:
- Reify: turn a pointer graph rooted at an
Rc<RefCell<T>>(orArc<Mutex<T>>) into a flat [ReifiedGraph] of nodes and edges, keyed by pointer identity, detecting cycles and preserving sharing. - Reflect: rebuild the original pointer graph from a [
ReifiedGraph], restoring the same sharing topology (one allocation per node id, even when many edges point to it).
With the default serde feature enabled, [ReifiedGraph] is
Serialize + Deserialize, which gives you JSON / postcard / etc.
serialization of arbitrary cyclic data essentially for free.
When to use it
- You want to dump or log a graph for debugging (an AST with shared sub-expressions, a circuit netlist, a scene graph).
- You want to send pointer-shaped state across a process boundary.
- You want to apply a structural transform (renumbering, GC, deduping)
that's awkward on the live
Rcgraph but easy on a flat node+edge form.
Design choices
- Node identity comes from [
Rc::as_ptr] (orArc::as_ptr) cast tousize. No traits or wrappers required on yourT. - Children are extracted by a closure you supply, so the library never guesses at the structure of your type.
- Node data is cloned into the [
ReifiedGraph] (useArc<Inner>insideTif cloning is expensive). - Reconstruction in [
reflect_graph] preserves sharing exactly: each [NodeId] becomes one [Rc] and is re-pointed everywhere it was referenced.
See the docs/phase2-graph-reification.md design note, and
the serialize_graph example for an end-to-end serde_json
round trip.
Examples
Round-trip a small Rc<RefCell<_>> tree through the flat form:
use ;
use RefCell;
use Rc;
let leaf = new;
let root = new;
// Flatten: 2 nodes, 1 edge
let graph = reify_graph;
assert_eq!;
assert_eq!;
// Rebuild, restoring the original sharing
let reconstructed = reflect_graph;
assert_eq!;
assert_eq!;
For Arc<Mutex<T>> graphs (the same pattern, thread-safe), see the
[arc] module's reify_graph_arc and reflect_graph_arc.