Graphs

After defining our dependencies, operations and values, we're finally ready to construct a graph and resolve its output!

let input_1 = InputNode::new(SomeNumber { value: 6 });
let input_2 = InputNode::new(SomeNumber { value: 7 });

// Derived is the root node of this graph.
let derived = DerivedNode::new(
    TwoNumbers::init(Rc::clone(&input_1), Rc::clone(&input_2)),
    Multiply,
    SomeNumber::default(),
);

// We'll need to create a visitor to resolve the graph. This keeps track
// of which nodes have been visited during depth-first traversal.
let mut visitor = GraphvizVisitor::new();

{
    // Let's put output in a scope so that all shared-references are dropped.
    let output = derived.resolve_root(&mut visitor).unwrap();
    assert_eq!(output.value, 42);
}
// Update one of the inputs.
input_1.update(60).unwrap();
{
    let output = derived.resolve_root(&mut visitor).unwrap();
    // The output should be updated on-demand.
    assert_eq!(output.value, 420);
}

Whilst the graph we've built so far is modest, and in no way justifies use of a dependency graph, we've demonstrated the basic building blocks of Depends. For applications which are likely to grow in complexity, this framework will allow us to maintain confidence in the correctness of our code.

Visualising with Graphviz

By enabling the graphviz feature, we can get a Graphviz representation of the graph:

// Use the special GraphvizVisitor to track the graph structure.
let mut visitor = GraphvizVisitor::new();

// Use `resolve` to _avoid_ clearing the visitor.
derived.resolve(&mut visitor).unwrap();

assert_eq!(
    visitor.render().unwrap(),
    r#"
digraph Dag {
  node_0 [label="SomeNumber"];
  node_1 [label="SomeNumber"];
  node_2 [label="SomeNumber"];
  node_0 -> node_2 [label="Multiply", class="TwoNumbersDep"];
  node_1 -> node_2 [label="Multiply", class="TwoNumbersDep"];
}
"#
    .trim()
);

This dot file format can be used with any Graphviz rendering tool to produce the following graph:

It's also possible to build graphs in Depends from the dot format. We'll show that off in a later chapter of this book.