sac-base 0.0.7

Base crate of the sac-signal and sac-control crates
Documentation
use crate::network::node::Node;
use core::{ops};
use alloc::boxed::Box;
use core::any::Any;
use crate::helper::iter::iter_n_inputs;

/// Operation to add two or more inputs together
pub struct Add {}

impl Add {
    /// Generate a new add operation
    ///
    /// ## Example
    /// ```rust
    /// use sac_base::operations::math::add::Add;
    /// let mut add = Add::new();
    /// let mut vec = Vec::new();
    /// vec.push(&[1.0, 3.0, 4.0][..]);
    /// vec.push(&[2.0][..]);
    /// vec.push(&[3.0][..]);
    /// // Sums up the three given inputs.
    /// add.process((vec, 3));
    /// assert_eq!(add.poll(), &[6.0, 3.0, 4.0][..]);
    /// ```
    pub fn new<T>() -> Node<T>
        where T: Copy + ops::Sub<Output=T> + ops::Add<Output=T> + Default
    {
        let storage = Box::new(0) as Box<dyn Any>;
        Node::new(storage,  |data_input, _input, output| {
            iter_n_inputs(data_input, output, |left: T, right: T| {
                return left + right;
            });
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use alloc::vec::Vec;

    #[test]
    fn test_add() {
        let mut inputs = Vec::new();
        inputs.push(&[1.0][..]);
        inputs.push(&[2.0][..]);

        let mut add = Add::new();
        add.process((inputs, 1));

        assert_eq!(&[3.0][..], add.poll());
    }

    #[test]
    fn test_multiple() {
        let mut inputs = Vec::new();
        inputs.push(&[1.0][..]);
        inputs.push(&[2.0][..]);
        inputs.push(&[3.0][..]);

        let mut add = Add::new();
        add.process((inputs, 1));

        assert_eq!(&[6.0][..], add.poll());
    }

    #[test]
    fn test_variable_len() {
        let mut inputs = Vec::new();
        inputs.push(&[1.0, 2.0, 3.0][..]);
        inputs.push(&[2.0, 1.0][..]);
        inputs.push(&[3.0][..]);

        let mut add = Add::new();
        add.process((inputs, 3));

        assert_eq!(&[6.0, 3.0, 3.0][..], add.poll());
    }


    #[test]
    fn test_multiple_runs() {
        let mut inputs = Vec::new();
        inputs.push(&[1.0][..]);
        inputs.push(&[2.0][..]);

        let mut add = Add::new();
        add.process((inputs, 1));


        let mut inputs = Vec::new();
        inputs.push(&[5.0][..]);
        inputs.push(&[6.0][..]);
        add.process((inputs, 1));

        assert_eq!(&[11.0][..], add.poll());
    }

    #[test]
    fn test_multiple_single() {
        let mut inputs = Vec::new();
        inputs.push(&[1.0][..]);

        let mut add = Add::new();
        add.process((inputs, 1));

        assert_eq!(&[1.0][..], add.poll());
    }
}