sac-base 0.0.7

Base crate of the sac-signal and sac-control crates
Documentation
use crate::network::node::Node;
use alloc::boxed::Box;
use core::any::Any;
use alloc::collections::VecDeque;
use alloc::vec::Vec;

/// Operation which shifts the input for the set amount of samples
/// Be aware, that the amount of shift, has to be allocated as buffer in the ram.
pub struct Shift<T> {
    buffer: VecDeque<Vec<T>>,
}

impl<T> Shift<T>
    where T: Copy + Default  + 'static
{

    /// Generate a new shifter
    ///
    /// ## Example
    /// ```rust
    /// use sac_base::operations::miscellaneous::shift::Shift;
    /// use sac_base::network::node::Node;
    /// let mut shift = Shift::new(3) as Node<f32>;
    /// let mut vec = Vec::new();
    /// vec.push(&[10.0, 3.0, -5.1][..]);
    /// shift.process((vec, 3));
    /// assert_eq!(shift.poll(), &[][..]);
    /// let mut vec = Vec::new();
    /// vec.push(&[1.0][..]);
    /// shift.process((vec, 1));
    /// assert_eq!(shift.poll(), &[][..]);
    /// let mut vec = Vec::new();
    /// vec.push(&[1.0][..]);
    /// shift.process((vec, 1));
    /// assert_eq!(shift.poll(), &[][..]);
    /// let mut vec = Vec::new();
    /// vec.push(&[1.0][..]);
    /// shift.process((vec, 1));
    /// assert_eq!(shift.poll(), &[10.0, 3.0, -5.1][..]);
    /// ```
    pub fn new(shift_len: usize) -> Node<T> {
        let mut shift: Shift<T> = Shift {
            buffer: VecDeque::with_capacity(shift_len),
        };

        for _i in 0..shift_len {
            shift.buffer.push_back(Vec::new());
        }

        let storage = Box::new(shift) as Box<dyn Any>;
        Node::new(storage, |data_input, store, output| {
            let shift: &mut Shift<T> = store.downcast_mut::<Shift<T>>().unwrap();
            let (inputs, _max_len) = data_input;
            inputs.into_iter().take(1).into_iter().for_each(|data| {
                shift.buffer.push_front(Vec::from(data));
                match shift.buffer.pop_back() {
                    Some(last) => {
                        *output = last;
                    },
                    None => {}
                }
            });
        })
    }
}

#[cfg(test)]
mod tests {

    use alloc::vec::Vec;
    use crate::operations::miscellaneous::shift::Shift;
    use crate::network::node::Node;

    #[test]
    fn test_shift() {
        let mut shift = Shift::new(3) as Node<f32>;
        let mut vec = Vec::new();
        vec.push(&[10.0, 3.0, -5.1][..]);
        shift.process((vec, 3));
        assert_eq!(shift.poll(), &[][..]);
        let mut vec = Vec::new();
        vec.push(&[1.0][..]);
        shift.process((vec, 1));
        assert_eq!(shift.poll(), &[][..]);
        let mut vec = Vec::new();
        vec.push(&[1.0][..]);
        shift.process((vec, 1));
        assert_eq!(shift.poll(), &[][..]);
        let mut vec = Vec::new();
        vec.push(&[1.0][..]);
        shift.process((vec, 1));
        assert_eq!(shift.poll(), &[10.0, 3.0, -5.1][..]);
    }
}