langis 0.1.0

A signal is a structure that can yield an infinite amount of data. The API is very similar to `std::iter::Iterator` but with the assumption that it will never end.
Documentation
//! This module contains signals that are created using functions in the main signal trait.

use super::Signal;
use core::cmp;
use core::marker::PhantomData;
use core::ops;

macro_rules! signal_for_bin_op {
    ($name:tt, $f:tt) => {
        #[derive(Clone)]
        pub struct $name<L, R> {
            pub(super) left: L,
            pub(super) right: R,
        }

        impl<L, R> Signal for $name<L, R>
        where
            L: Signal,
            R: Signal,
            L::Type: ops::$name<R::Type>,
        {
            type Type = <L::Type as ops::$name<R::Type>>::Output;

            #[inline]
            fn next(&mut self) -> Self::Type {
                ops::$name::$f(self.left.next(), self.right.next())
            }
        }
    };
}

signal_for_bin_op!(Add, add);
signal_for_bin_op!(Sub, sub);
signal_for_bin_op!(Mul, mul);
signal_for_bin_op!(Div, div);
signal_for_bin_op!(Rem, rem);
signal_for_bin_op!(BitAnd, bitand);
signal_for_bin_op!(BitOr, bitor);
signal_for_bin_op!(BitXor, bitxor);
signal_for_bin_op!(Shr, shr);
signal_for_bin_op!(Shl, shl);

/// Negates a signal.
#[derive(Clone)]
pub struct Neg<S> {
    pub(super) signal: S,
}

impl<S> Signal for Neg<S>
where
    S: Signal,
    S::Type: ops::Neg,
{
    type Type = <S::Type as ops::Neg>::Output;

    #[inline]
    fn next(&mut self) -> Self::Type {
        ops::Neg::neg(self.signal.next())
    }
}

/// Returns the minimum of two signals,
#[derive(Clone)]
pub struct Min<A, B> {
    pub(super) a: A,
    pub(super) b: B,
}

impl<A, B> Signal for Min<A, B>
where
    A: Signal,
    B: Signal<Type = A::Type>,
    A::Type: Ord,
{
    type Type = A::Type;

    fn next(&mut self) -> Self::Type {
        let a = self.a.next();
        let b = self.b.next();

        if a < b {
            a
        } else {
            b
        }
    }
}

/// Returns the maximum of two signals,
#[derive(Clone)]
pub struct Max<A, B> {
    pub(super) a: A,
    pub(super) b: B,
}

impl<A, B> Signal for Max<A, B>
where
    A: Signal,
    B: Signal<Type = A::Type>,
    A::Type: Ord,
{
    type Type = A::Type;

    fn next(&mut self) -> Self::Type {
        let a = self.a.next();
        let b = self.b.next();

        if a > b {
            a
        } else {
            b
        }
    }
}

/// Clamps the values of `S` between `Min` and `Max`.
#[derive(Clone)]
pub struct Clamp<S, Min, Max> {
    pub(super) signal: S,
    pub(super) min: Min,
    pub(super) max: Max,
}

impl<S, Min, Max> Signal for Clamp<S, Min, Max>
where
    S: Signal,
    Min: Signal<Type = S::Type>,
    Max: Signal<Type = S::Type>,
    S::Type: cmp::Ord,
{
    type Type = S::Type;

    fn next(&mut self) -> Self::Type {
        let val = self.signal.next();
        let min = self.min.next();
        let max = self.max.next();

        if val < min {
            min
        } else if val > max {
            max
        } else {
            val
        }
    }
}

/// Maps a signal to another using a function.
#[derive(Clone)]
pub struct Map<S, F> {
    pub(super) signal: S,
    pub(super) map: F,
}

impl<S, F, T> Signal for Map<S, F>
where
    S: Signal,
    F: FnMut(S::Type) -> T,
{
    type Type = T;

    #[inline]
    fn next(&mut self) -> Self::Type {
        (self.map)(self.signal.next())
    }
}

#[derive(Clone)]
pub struct Filter<S, F> {
    pub(super) signal: S,
    pub(super) predicate: F,
}

impl<S, F> Signal for Filter<S, F>
where
    S: Signal,
    F: FnMut(&S::Type) -> bool,
{
    type Type = S::Type;

    fn next(&mut self) -> Self::Type {
        let mut candidate = self.signal.next();

        while !(self.predicate)(&candidate) {
            candidate = self.signal.next();
        }

        candidate
    }
}

#[derive(Clone)]
pub struct FilterMap<S, F> {
    pub(super) signal: S,
    pub(super) predicate: F,
}

impl<S, F, T> Signal for FilterMap<S, F>
where
    S: Signal,
    F: FnMut(S::Type) -> Option<T>,
{
    type Type = T;

    fn next(&mut self) -> Self::Type {
        loop {
            match (self.predicate)(self.signal.next()) {
                Some(value) => return value,
                None => continue,
            }
        }
    }
}

/// Clones the values of a signal. It is useful to turn a `Signal<Type = &T>` into a
/// `Signal<Type = T>`.
#[derive(Clone)]
pub struct Cloned<S> {
    pub(super) signal: S,
}

impl<'a, S, T> Signal for Cloned<S>
where
    T: 'a + Clone,
    S: Signal<Type = &'a T>,
{
    type Type = T;

    #[inline]
    fn next(&mut self) -> Self::Type {
        self.signal.next().clone()
    }
}

/// A signal that calls a function with a reference to each value before yielding it.
#[derive(Clone)]
pub struct Inspect<S, F> {
    pub(super) signal: S,
    pub(super) inspect: F,
}

impl<S, F> Signal for Inspect<S, F>
where
    S: Signal,
    F: FnMut(&S::Type),
{
    type Type = S::Type;

    #[inline]
    fn next(&mut self) -> Self::Type {
        let result = self.signal.next();
        (self.inspect)(&result);
        result
    }
}

/// An signal that yield the values of two other signals.
#[derive(Clone)]
pub struct Zip<A, B> {
    pub(super) a: A,
    pub(super) b: B,
}

impl<A, B> Signal for Zip<A, B>
where
    A: Signal,
    B: Signal,
{
    type Type = (A::Type, B::Type);

    #[inline]
    fn next(&mut self) -> Self::Type {
        (self.a.next(), self.b.next())
    }
}

/// Uses the `Into` trait to turn an signal into another.
#[derive(Clone)]
pub struct Into<S, T> {
    pub(super) signal: S,
    pub(super) _target: PhantomData<T>,
}

impl<S, T> Signal for Into<S, T>
where
    S: Signal,
    S::Type: core::convert::Into<T>,
{
    type Type = T;

    #[inline]
    fn next(&mut self) -> Self::Type {
        self.signal.next().into()
    }
}

/// Skips the values of a signal.
#[derive(Clone)]
pub struct Skip<S> {
    pub(super) signal: S,
    pub(super) n: usize,
}

impl<S> Signal for Skip<S>
where
    S: Signal,
{
    type Type = S::Type;

    fn next(&mut self) -> Self::Type {
        if self.n == 0 {
            self.signal.next()
        } else {
            for _ in 0..self.n {
                self.signal.next();
            }

            self.n = 0;

            self.signal.next()
        }
    }
}

/// An iterator that yield the values of a signal.
#[derive(Clone)]
pub struct IntoIter<S> {
    pub(super) signal: S,
}

impl<S> Iterator for IntoIter<S>
where
    S: Signal,
{
    type Item = S::Type;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        Some(self.signal.next())
    }
}