Skip to main content

graph

Macro graph 

Source
macro_rules! graph {
    (
        $($items:tt)*
    ) => { ... };
}
Expand description

Declarative macro for constructing graphs with minimal syntax.

The graph! macro allows you to define graphs using a concise, declarative syntax that reduces boilerplate and improves readability compared to the traditional Graph API.

§Syntax

use streamweave::graph;

let graph = graph! {
    node1: Node1::new("node1"),
    node2: Node2::new("node2"),
    // Optional connections section
    ; node1.out => node2.in
};

§Node Definitions

Nodes are defined using the pattern name: NodeInstance, where:

  • name is an identifier that will be used to reference the node in connections
  • NodeInstance is an expression that evaluates to a node instance
  • Multiple nodes are separated by commas

§Connections

Connections are optional and specified after a semicolon. Supported patterns:

§Node-to-Node Connections

graph! {
    source: SourceNode::new(),
    sink: SinkNode::new(),
    ; source.out => sink.in
};

All ports must be explicitly named. No default ports or sequential shortcuts.

§Graph Inputs

§With Initial Value

graph! {
    node: Node::new(),
    graph.config: 42i32 => node.in
};

The value is sent via a channel when the graph is built.

§Without Value (Runtime Connection)

graph! {
    node: Node::new(),
    ; graph.input => node.in
};

External channels must be connected at runtime.

§Graph Outputs

graph! {
    node: Node::new(),
    node.out => graph.output
};

§Restrictions

  • Reserved Node Name: Node names cannot be "graph" - this name is reserved for graph I/O namespace
  • Unique Node Names: All node names must be unique within the graph
  • Fan-Out Not Supported: Each output port can only connect to one input port. Attempting to connect the same source port to multiple targets will panic at build time.
  • Fan-In Allowed: Multiple sources can connect to the same target port (fan-in is supported)
  • Explicit Ports Required: All connections must explicitly specify port names on both source and target sides

§Examples

§Simple Linear Pipeline

let graph = graph! {
    producer: ProducerNode::new(),
    transform: TransformNode::new(),
    sink: SinkNode::new(),
    producer.out => transform.in,
    transform.out => sink.in
};

§Graph I/O with Values

let graph = graph! {
    transform: TransformNode::new(),
    graph.config: 100i32 => transform.in,
    transform.out => graph.result
};

§Fan-In Pattern

let graph = graph! {
    source1: SourceNode::new(),
    source2: SourceNode::new(),
    merge: MergeNode::new(),
    ; source1.out => merge.in1,
      source2.out => merge.in2
};

§Error Handling

The macro will panic at build time if:

  • A node is named "graph" (compile-time error via validate_node_name!)
  • Fan-out is detected (runtime panic in GraphBuilder::connect)
  • Invalid ports or nodes are referenced (errors from Graph::add_edge)

§See Also

  • GraphBuilder - Fluent API alternative
  • Graph - Core graph type
  • Examples in examples/ directory