logic_mesh/blocks/math/
sub.rs

1// Copyright (c) 2022-2023, Radu Racariu.
2
3use 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, Value};
12
13use crate::{blocks::InputImpl, blocks::OutputImpl};
14
15/// Performs an subtraction of 2 numbers.
16/// The operation would take into account the units of those input's values,
17/// if the units are not convertible, the block would be in an error state.
18#[block]
19#[derive(BlockProps, Debug)]
20#[category = "math"]
21pub struct Sub {
22    #[input(kind = "Number")]
23    pub a: InputImpl,
24    #[input(kind = "Number")]
25    pub b: InputImpl,
26    #[output(kind = "Number")]
27    pub out: OutputImpl,
28}
29
30impl Block for Sub {
31    async fn execute(&mut self) {
32        self.read_inputs_until_ready().await;
33
34        if let (Some(Value::Number(a)), Some(Value::Number(b))) =
35            (&self.a.get_value(), &self.b.get_value())
36        {
37            match *a - *b {
38                Ok(res) => self.out.set(res.into()),
39                Err(e) => {
40                    log::error!("Error while subtracting: {}", e);
41                    self.set_state(BlockState::Fault);
42                }
43            }
44        }
45    }
46}
47
48#[cfg(test)]
49mod test {
50
51    use crate::{
52        base::block::test_utils::write_block_inputs,
53        base::{block::Block, input::input_reader::InputReader},
54        blocks::math::Sub,
55    };
56
57    #[tokio::test]
58    async fn test_sub_block() {
59        let mut block = Sub::new();
60
61        for _ in
62            write_block_inputs(&mut [(&mut block.a, 10.into()), (&mut block.b, 3.into())]).await
63        {
64            block.read_inputs().await;
65        }
66
67        block.execute().await;
68        assert_eq!(block.out.value, 7.into());
69    }
70}