pub enum CompositionNode {
Stage {
id: StageId,
config: Option<BTreeMap<String, Value>>,
},
RemoteStage {
url: String,
input: NType,
output: NType,
},
Const {
value: Value,
},
Sequential {
stages: Vec<CompositionNode>,
},
Parallel {
branches: BTreeMap<String, CompositionNode>,
},
Branch {
predicate: Box<CompositionNode>,
if_true: Box<CompositionNode>,
if_false: Box<CompositionNode>,
},
Fanout {
source: Box<CompositionNode>,
targets: Vec<CompositionNode>,
},
Merge {
sources: Vec<CompositionNode>,
target: Box<CompositionNode>,
},
Retry {
stage: Box<CompositionNode>,
max_attempts: u32,
delay_ms: Option<u64>,
},
Let {
bindings: BTreeMap<String, CompositionNode>,
body: Box<CompositionNode>,
},
}Expand description
A composition graph node. The core AST for Noether’s composition language.
Variants§
Stage
Leaf node: reference to a stage by its content hash.
The optional config provides static parameter values merged with
the pipeline input before the stage executes. This separates data
flow (from the pipeline) from configuration (from the graph).
RemoteStage
Call a remote Noether API endpoint over HTTP.
The declared input and output types are verified by the type checker
at build time — the remote server does not need to be running during
noether build. In native builds, execution uses reqwest. In browser
builds, the JS runtime makes a fetch() call.
Fields
Const
Emits a constant JSON value, ignoring its input entirely. Used to inject literal strings, numbers, or objects into a pipeline.
Sequential
A >> B >> C: output of each stage feeds the next.
Fields
stages: Vec<CompositionNode>Parallel
Execute branches concurrently, merge outputs into a Record keyed by
branch name. Each branch receives input[branch_name] if the input is
a Record containing that key; otherwise it receives the full input.
Const branches ignore their input entirely — use them for literals.
Fields
branches: BTreeMap<String, CompositionNode>Branch
Conditional routing based on a predicate stage.
Fanout
Source output sent to all targets concurrently.
Merge
Multiple sources merge into a single target.
Retry
Retry a stage up to max_attempts times on failure.
Let
Bind named intermediate computations and reference them in body.
Each binding sub-node receives the outer Let input (the same value
passed to the Let node). After all bindings have produced a value, the
body runs against an augmented input record:
{ ...outer-input fields, <binding-name>: <binding-output>, ... }
Bindings with the same name as an outer-input field shadow it. This
makes it possible to carry original-input fields into stages later in a
Sequential pipeline — the canonical example is scan → hash → diff,
where diff needs state_path from the original input but hash
would otherwise erase it.
All bindings are scheduled concurrently — there are no inter-binding
references. If you need a binding to depend on another, wrap it in a
nested Sequential.
Trait Implementations§
Source§impl Clone for CompositionNode
impl Clone for CompositionNode
Source§fn clone(&self) -> CompositionNode
fn clone(&self) -> CompositionNode
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more