logic_mesh/blocks/logic/
latch.rs

1// Copyright (c) 2022-2024, 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/// Outputs the input value if the condition is true.
16#[block]
17#[derive(BlockProps, Debug)]
18#[category = "logic"]
19pub struct Latch {
20    #[input(name = "in", kind = "Null")]
21    pub input: InputImpl,
22    #[input(kind = "Bool")]
23    pub condition: InputImpl,
24    #[output(kind = "Null")]
25    pub out: OutputImpl,
26}
27
28impl Block for Latch {
29    async fn execute(&mut self) {
30        self.read_inputs_until_ready().await;
31
32        let input = self.input.get_value();
33        let condition = self.condition.get_value();
34
35        if let (Some(Value::Bool(condition)), Some(input)) = (condition, input) {
36            if condition.value {
37                self.out.set(input.clone());
38            } else {
39                self.out.set(Value::Null);
40            }
41        }
42    }
43}
44
45#[cfg(test)]
46mod test {
47
48    use libhaystack::val::Value;
49
50    use crate::{
51        base::block::test_utils::write_block_inputs,
52        base::{block::Block, input::input_reader::InputReader},
53        blocks::logic::latch::Latch,
54    };
55
56    #[tokio::test]
57    async fn test_latch_false() {
58        let mut block = Latch::new();
59
60        for _ in write_block_inputs(&mut [
61            (&mut block.input, 42.into()),
62            (&mut block.condition, false.into()),
63        ])
64        .await
65        {
66            block.read_inputs().await;
67        }
68
69        block.execute().await;
70        assert_eq!(block.out.value, Value::Null);
71    }
72
73    #[tokio::test]
74    async fn test_latch_true() {
75        let mut block = Latch::new();
76
77        for _ in write_block_inputs(&mut [
78            (&mut block.input, 42.into()),
79            (&mut block.condition, true.into()),
80        ])
81        .await
82        {
83            block.read_inputs().await;
84        }
85
86        block.execute().await;
87        assert_eq!(block.out.value, 42.into());
88    }
89}