use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub};
use crate::{
Signal,
map::{Map, map},
zip::{Zip, zip},
};
macro_rules! define_binary_op {
($fn_name:ident, $trait:ident, $method:ident) => {
#[doc = concat!(
"Combines two `Signal` sources using the `",
stringify!($method),
"` operator."
)]
#[allow(clippy::type_complexity)]
pub fn $fn_name<A, B>(
a: A,
b: B,
) -> Map<
Zip<A, B>,
fn((A::Output, B::Output)) -> <A::Output as $trait<B::Output>>::Output,
<A::Output as $trait<B::Output>>::Output,
>
where
A: Signal + 'static,
B: Signal + 'static,
A::Output: $trait<B::Output> + Clone,
B::Output: Clone,
{
let zip = zip(a, b);
map(zip, |(a, b)| a.$method(b))
}
};
}
define_binary_op!(add, Add, add);
define_binary_op!(sub, Sub, sub);
define_binary_op!(mul, Mul, mul);
define_binary_op!(div, Div, div);
define_binary_op!(rem, Rem, rem);
define_binary_op!(bitand, BitAnd, bitand);
define_binary_op!(bitor, BitOr, bitor);
define_binary_op!(bitxor, BitXor, bitxor);
define_binary_op!(shl, Shl, shl);
define_binary_op!(shr, Shr, shr);
#[allow(clippy::type_complexity)]
pub fn max<A, B, T>(a: A, b: B) -> Map<Zip<A, B>, fn((T, T)) -> T, T>
where
A: Signal<Output = T>,
B: Signal<Output = T>,
T: Ord + Clone + 'static,
{
let zip = zip(a, b);
map(zip, |(a, b)| core::cmp::max(a, b))
}
#[allow(clippy::type_complexity)]
pub fn min<A, B, T>(a: A, b: B) -> Map<Zip<A, B>, fn((T, T)) -> T, T>
where
A: Signal<Output = T>,
B: Signal<Output = T>,
T: Ord + Clone + 'static,
{
let zip = zip(a, b);
map(zip, |(a, b)| core::cmp::min(a, b))
}
#[cfg(feature = "timer")]
pub(crate) async fn sleep(duration: core::time::Duration) {
#[cfg(target_arch = "wasm32")]
{
use gloo_timers::future::sleep;
sleep(duration).await;
}
#[cfg(not(target_arch = "wasm32"))]
{
use async_io::Timer;
Timer::after(duration).await;
}
}