anchor_chain/
node.rs

1//! Module providing foundational structures for building chains.
2//!
3//! This module defines a `Node` trait for asynchronous operations and
4//! constructs (`Link` and `End`) to create chains of these operations.
5
6use std::marker::PhantomData;
7
8use async_trait::async_trait;
9#[cfg(feature = "tracing")]
10use tracing::instrument;
11
12use crate::error::AnchorChainError;
13
14/// Represents a node that can process an input to produce an output.
15///
16/// The `Node` trait defines a generic processing operation with a
17/// specified input and output type. Implementors of this trait can be
18/// composed together to form a processing chain.
19#[async_trait]
20pub trait Node: std::fmt::Debug {
21    /// The input type for the node.
22    type Input;
23    /// The output type for the node.
24    type Output;
25
26    /// Asynchronously processes the given input, returning the output. When
27    /// chained together the output type of one node must match the input of
28    /// the next node in the chain.
29    async fn process(&self, input: Self::Input) -> Result<Self::Output, AnchorChainError>;
30}
31
32/// A no-op node that passes input through unchanged.
33#[derive(Debug)]
34pub struct NoOpNode<T> {
35    _marker: PhantomData<T>,
36}
37
38impl<T> NoOpNode<T> {
39    /// Creates a new `NoOpNode`.
40    pub fn new() -> Self {
41        Self {
42            _marker: PhantomData,
43        }
44    }
45}
46
47impl<T> Default for NoOpNode<T> {
48    fn default() -> Self {
49        Self::new()
50    }
51}
52
53#[async_trait]
54impl<T> Node for NoOpNode<T>
55where
56    T: Send + Sync + std::fmt::Debug,
57{
58    /// The input type for the NoOpNode.
59    type Input = T;
60    /// The output type for the NoOpNode.
61    type Output = T;
62
63    /// Returns the input unchanged.
64    #[cfg_attr(feature = "tracing", instrument(skip(self)))]
65    async fn process(&self, input: Self::Input) -> Result<Self::Output, AnchorChainError> {
66        Ok(input)
67    }
68}