use uuid::Uuid;
use crate::base::{
block::{Block, BlockDesc, BlockProps, BlockState},
input::{InputProps, input_reader::InputReader},
output::Output,
};
use libhaystack::val::{Number, Value, kind::HaystackKind};
use crate::{blocks::InputImpl, blocks::OutputImpl};
#[block]
#[derive(BlockProps, Debug)]
#[category = "math"]
#[input(kind = "Number", count = 16)]
pub struct Mul {
#[output(kind = "Number")]
pub out: OutputImpl,
}
impl Block for Mul {
async fn execute(&mut self) {
self.read_inputs_until_ready().await;
let mut val: Option<Number> = None;
let mut cnt = 0;
for el in self
.inputs()
.into_iter()
.filter_map(|input| match input.get_value().as_ref() {
Some(Value::Number(num)) => Some(*num),
_ => None,
})
{
cnt += 1;
if let Some(v) = val {
let res = v * el;
if res.is_err() {
val = None;
break;
}
match res {
Ok(res) => {
val.replace(res);
}
Err(_) => {
val = None;
break;
}
}
} else {
val = Some(el);
}
}
if cnt > 1
&& let Some(res) = val
{
self.out.set(res.into())
}
}
}
#[cfg(test)]
mod test {
use crate::{
base::block::{Block, BlockProps},
base::input::input_reader::InputReader,
blocks::math::Mul,
};
#[tokio::test]
async fn test_mul_block() {
let mut block = Mul::new();
{
let in1 = block.get_input_mut("in0").unwrap();
in1.increment_conn();
in1.writer()
.send((3.into(), crate::base::Status::Ok))
.unwrap();
block.read_inputs().await;
}
{
let in16 = block.get_input_mut("in15").unwrap();
in16.increment_conn();
in16.writer()
.send((3.into(), crate::base::Status::Ok))
.unwrap();
}
block.execute().await;
assert_eq!(block.out.value, 9.into());
}
}