siraph 0.1.2

A node-based digital signal processing crate
Documentation
#![cfg(test)]

use siraph::{Graph, Input, Node, Output, Register, Sink};

pub struct Add {
    left: Input<i32>,
    right: Input<i32>,
    result: Output<i32>,
}

impl Add {
    pub fn new() -> Self {
        Self {
            left: Input::default(),
            right: Input::default(),
            result: Output::default(),
        }
    }
}

impl Node for Add {
    fn register(&self, r: &mut Register) {
        r.input("left", &self.left);
        r.input("right", &self.right);
        r.output("result", &self.result);
    }

    fn process(&mut self) {
        if self.result.is_used() {
            let left = self.left.get().unwrap_or_default();
            let right = self.right.get().unwrap_or_default();
            self.result.set(left + right)
        }
    }

    fn reset(&mut self) {}
}

pub struct Counter {
    value: i32,
    output: Output<i32>,
}

impl Counter {
    pub fn new(start: i32) -> Self {
        Self {
            value: start,
            output: Output::default(),
        }
    }
}

impl Node for Counter {
    fn register(&self, r: &mut Register) {
        r.output("output", &self.output);
    }

    fn process(&mut self) {
        self.output.set(self.value);
        self.value += 1;
    }

    fn reset(&mut self) {}
}

#[test]
fn test_basic_use() {
    let mut graph = Graph::default();
    let a = graph.insert(Counter::new(0));

    let mut sink = graph.sink(a, "output").unwrap();

    for i in 0i32..1000 {
        assert_eq!(sink.next(), Some(i));
    }
}

#[test]
fn test_basic_plug() {
    let mut graph = Graph::default();
    let a = graph.insert(Counter::new(0));
    let b = graph.insert(Counter::new(2));
    let c = graph.insert(Add::new());

    graph.plug(a, "output", c, "left").unwrap();
    graph.plug(b, "output", c, "right").unwrap();

    let mut sink = graph.sink(c, "result").unwrap();

    for i in 0..1000 {
        assert_eq!(sink.next(), Some(2 + i * 2));
    }
}

#[test]
#[should_panic(expected = "ERROR")]
fn test_cycle_simple() {
    let mut graph = Graph::default();

    let a = graph.insert(Add::new());

    graph.plug(a, "result", a, "left").expect("ERROR");
}

#[test]
#[should_panic(expected = "ERROR")]
fn test_cycle_multiple() {
    let mut graph = Graph::default();

    let a = graph.insert(Add::new());
    let b = graph.insert(Add::new());
    let c = graph.insert(Add::new());

    graph.plug(a, "result", b, "left").unwrap();
    graph.plug(b, "result", c, "left").unwrap();
    graph.plug(c, "result", a, "left").expect("ERROR");
}

#[test]
fn test_stable_node_handles() {
    let mut graph = Graph::default();

    let a = graph.insert(Add::new());
    let b = graph.insert(Counter::new(0));

    graph.remove(a).unwrap();

    // if handles are not stable, `b` should
    // not be a valid handle anymore.
    let _: Sink<'_, i32> = graph.sink(b, "output").unwrap();
}