Macro conflagrate::graph
source · [−]graph!() { /* proc-macro */ }
Expand description
Defines the control flow graph of an application.
The graph!
macro defines a control flow graph that can be run as a stand-alone application
or called as a subgraph from within another graph. The syntax follows the standard
DOT language excepting a few new, non-standard attributes that can
be applied to nodes and edges that conflagrate uses to construct the executable application
logic.
Node Attributes
type
– Thenodetype
associated with the node the in graph, which is a block of executable code that takes as input the output from the previous node and provides as output the input to the next node. Multiple nodes in the graph can use the samenodetype
to facillitate more code reuse.start
– Labels the node to start the graph from. Only one node may be labeled with thestart
attribute.branch
– Tells conflagrate how to handle a node that has more than one node trailing it in the graph. May take the following values:parallel
(default) – Conflagrate executes all trailing nodes simultaneously in parallel. The return value from the node is cloned and passed separately to each tail. If thebranch
attribute is omitted, this value is assumed.matcher
– Conflagrate executes only one trailing node determined by the output of the matcher node. This puts constraints on the required return type of thenodetype
(seenodetype
: Matcher).resultmatcher
– A variant ofmatcher
that matches on aResult
instead of aString
(seenodetype
: Result Matcher).
Edge Attributes
value
– Used with nodes with thebranch=matcher
attribute (see above). The return value of the matcher node is compared against this (string) value. If it matches, this edge is followed to determine the next node to be executed in the graph.
Examples
Trivial Graph
A single-node graph that just prints the text Hello, world!
.
#[nodetype]
pub fn HelloWorld() {
println!("Hello, world!");
}
graph!{
digraph {
start[type=HelloWorld, start=true];
}
}
fn main() {
Graph::run(());
}
Simple Loop
A simple loop that asks the user if they wish to exit (type yes
to exit).
#[nodetype]
pub fn AskExit() -> (String, ()) {
let mut response = String::new();
println!("Exit loop?");
std::io::stdin().read_line(&mut response).unwrap();
response.truncate(response.len() - 1);
(response, ())
}
#[nodetype]
pub async fn DoNothing() {}
graph!{
digraph Loop {
ask_exit[type=AskExit, branch=matcher, start=true];
end[type=DoNothing];
ask_exit -> end [value=yes];
ask_exit -> ask_exit;
}
}
fn main() {
Loop::run(())
}
This graph makes use of the matcher
branching logic. The ask_exit
node has two tails,
one that goes to the end
node with the value=yes
attribute, and another that goes back to
the ask_exit
node with no attributes. The matching logic chooses which trailing node to
execute next based on the first element in the tuple output from the AskExit
nodetype
function. The second element of the tuple is then passed as input to the chosen following node.
See Also
nodetype
– Macro associating functions with nodes.dependency
– Macro associating a function providing a resource with the name of the function, providing that resource tonodetype
s that reference them.