logic_mesh/blocks/math/
mul.rs1use uuid::Uuid;
4
5use crate::base::{
6 block::{Block, BlockDesc, BlockProps, BlockState},
7 input::{input_reader::InputReader, Input, InputProps},
8 output::Output,
9};
10
11use libhaystack::val::{kind::HaystackKind, Number, Value};
12
13use crate::{blocks::InputImpl, blocks::OutputImpl};
14
15#[block]
20#[derive(BlockProps, Debug)]
21#[category = "math"]
22#[input(kind = "Number", count = 16)]
23pub struct Mul {
24 #[output(kind = "Number")]
25 pub out: OutputImpl,
26}
27
28impl Block for Mul {
29 async fn execute(&mut self) {
30 self.read_inputs_until_ready().await;
31
32 let mut val: Option<Number> = None;
33 let mut cnt = 0;
34 for el in self
35 .inputs()
36 .into_iter()
37 .filter_map(|input| match input.get_value().as_ref() {
38 Some(Value::Number(num)) => Some(*num),
39 _ => None,
40 })
41 {
42 cnt += 1;
43
44 if let Some(v) = val {
45 let res = v * el;
46
47 if res.is_err() {
48 val = None;
49 break;
50 }
51
52 match res {
53 Ok(res) => {
54 val.replace(res);
55 }
56 Err(_) => {
57 val = None;
58 break;
59 }
60 }
61 } else {
62 val = Some(el);
63 }
64 }
65
66 if cnt > 1 {
67 if let Some(res) = val {
68 self.out.set(res.into())
69 }
70 }
71 }
72}
73
74#[cfg(test)]
75mod test {
76
77 use crate::base::input::input_reader::InputReader;
78 use crate::{
79 base::block::{Block, BlockProps},
80 blocks::math::Mul,
81 };
82
83 #[tokio::test]
84 async fn test_mul_block() {
85 let mut block = Mul::new();
86
87 {
88 let in1 = block.get_input_mut("in0").unwrap();
89 in1.increment_conn();
90 in1.writer().try_send(3.into()).unwrap();
91 block.read_inputs().await;
92 }
93
94 {
95 let in16 = block.get_input_mut("in15").unwrap();
96 in16.increment_conn();
97 in16.writer().try_send(3.into()).unwrap();
98 }
99
100 block.execute().await;
101 assert_eq!(block.out.value, 9.into());
102 }
103}