logic_mesh/blocks/collections/
get.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/// Gets the element specified at key from the input and outputs the
16/// element's value.
17#[block]
18#[derive(BlockProps, Debug)]
19#[category = "collections"]
20pub struct GetElement {
21    #[input(name = "input", kind = "Null")]
22    pub input: InputImpl,
23    #[input(name = "key", kind = "Null")]
24    pub key: InputImpl,
25    #[output(kind = "Null")]
26    pub out: OutputImpl,
27}
28
29impl Block for GetElement {
30    async fn execute(&mut self) {
31        self.read_inputs_until_ready().await;
32
33        if let Some(value) = match (self.input.get_value(), self.key.get_value()) {
34            (Some(Value::Dict(dict)), Some(Value::Str(key))) => dict.get(key.as_str()),
35            (Some(Value::List(list)), Some(Value::Number(index))) => list.get(index.value as usize),
36            _ => None,
37        } {
38            self.out.set(value.clone());
39        } else {
40            self.out.set(Value::Null);
41        }
42    }
43}
44
45#[cfg(test)]
46mod test {
47    use libhaystack::val::Dict;
48    use libhaystack::{dict, val::Value};
49
50    use crate::{
51        base::block::test_utils::write_block_inputs,
52        base::{block::Block, input::input_reader::InputReader},
53        blocks::collections::GetElement,
54    };
55
56    #[tokio::test]
57    async fn test_get_element_block() {
58        let mut block = GetElement::new();
59
60        for _ in write_block_inputs(&mut [
61            (&mut block.input, (dict! {"a" => 1.into()}).into()),
62            (&mut block.key, "a".into()),
63        ])
64        .await
65        {
66            block.read_inputs().await;
67        }
68
69        block.execute().await;
70        assert_eq!(block.out.value, 1.into());
71
72        write_block_inputs(&mut [(&mut block.key, "x".into())]).await;
73        block.execute().await;
74        assert_eq!(block.out.value, Value::Null);
75
76        for _ in
77            write_block_inputs(&mut [(&mut block.input, "".into()), (&mut block.key, "a".into())])
78                .await
79        {
80            block.read_inputs().await;
81        }
82
83        block.execute().await;
84        assert_eq!(block.out.value, Value::Null);
85
86        for _ in write_block_inputs(&mut [
87            (&mut block.input, (vec![1.into(), 2.into()]).into()),
88            (&mut block.key, 1.into()),
89        ])
90        .await
91        {
92            block.read_inputs().await;
93        }
94
95        block.execute().await;
96        assert_eq!(block.out.value, 2.into());
97
98        write_block_inputs(&mut [(&mut block.key, 100.into())]).await;
99        block.execute().await;
100        assert_eq!(block.out.value, Value::Null);
101    }
102}