Skip to main content

node

Attribute Macro node 

Source
#[node]
Expand description

Attribute macro for impl MutableNode blocks.

Generates fn upstreams() and/or impl StreamPeekRef<T> to eliminate boilerplate in custom node definitions. See MutableNode for the full attribute syntax.

Scope requirement: the generated upstreams() body calls AsUpstreamNodes unqualified, so AsUpstreamNodes must be in scope. use wingfoil::* satisfies this; selective imports must add use wingfoil::AsUpstreamNodes explicitly. Attribute macro that reduces boilerplate in MutableNode implementations.

Place #[node(...)] on an impl MutableNode for MyType block. It can:

  • Inject fn upstreams() from active = [field1, field2] and/or passive = [field3]
  • Emit a separate impl StreamPeekRef<T> from output = field_name: FieldType

Fields listed as active or passive must implement AsUpstreamNodes (Rc<dyn Node>, Rc<dyn Stream<T>>, or Vec of either).

If neither active nor passive is specified, no upstreams() is injected โ€” the default UpStreams::none() from MutableNode is used (source node), or you can write upstreams() manually in the impl block for complex cases (e.g. Dep<T>).

ยงExamples

โ“˜
// Transform node: active upstream, stream output
#[node(active = [upstream], output = value: OUT)]
impl<IN, OUT: Element> MutableNode for MapStream<IN, OUT> {
    fn cycle(&mut self, _state: &mut GraphState) -> anyhow::Result<bool> {
        self.value = (self.func)(self.upstream.peek_value());
        Ok(true)
    }
}

// Sink node: active upstream, no output
#[node(active = [upstream])]
impl<IN> MutableNode for ConsumerNode<IN> {
    fn cycle(&mut self, state: &mut GraphState) -> anyhow::Result<bool> { ... }
}

// Source node with output (upstreams default to none)
#[node(output = value: T)]
impl<T: Element> MutableNode for ConstantStream<T> {
    fn cycle(&mut self, _state: &mut GraphState) -> anyhow::Result<bool> { Ok(true) }
}

// Mixed: passive + active upstreams, output
#[node(passive = [upstream], active = [trigger], output = value: T)]
impl<T: Element> MutableNode for SampleStream<T> { ... }

// Complex upstreams (Dep<T> etc.) โ€” write upstreams() manually, use #[node] for output only
#[node(output = value: OUT)]
impl<IN1: 'static, IN2: 'static, OUT: Element> MutableNode for BiMapStream<IN1, IN2, OUT> {
    fn cycle(&mut self, ...) -> anyhow::Result<bool> { ... }
    fn upstreams(&self) -> UpStreams { /* Dep<T> logic */ }
}