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);
#[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())
}
}
#[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
}
}
}
#[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
}
}
}
#[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
}
}
}
#[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,
}
}
}
}
#[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()
}
}
#[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
}
}
#[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())
}
}
#[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()
}
}
#[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()
}
}
}
#[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())
}
}