logic_mesh/blocks/logic/
latch.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, Value};
12
13use crate::{blocks::InputImpl, blocks::OutputImpl};
14
15#[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}