Skip to main content

std_mel/data/string_map/
block.rs

1use super::*;
2use melodium_macro::mel_treatment;
3use std::collections::HashMap;
4use std::sync::Arc;
5
6/// When `value` is received, produce a single-entry `StringMap` with `key` → `value` and emit it on `map`.
7#[mel_treatment(
8    input value Block<string>
9    output map Block<StringMap>
10)]
11pub async fn entry(key: string) {
12    if let Ok(value) = value.recv_one_as::<String>().await {
13        let mut new_map = HashMap::new();
14        new_map.insert(key.clone(), value);
15        let new_map = StringMap { map: new_map };
16        let _ = map.send_one(Value::Data(Arc::new(new_map))).await;
17    }
18}
19
20/// Receive one `StringMap` block and emit the value stored under `key` as `Option<string>` on `value`.
21///
22/// Emits `none` if the key is absent.
23#[mel_treatment(
24    input map Block<StringMap>
25    output value Block<Option<string>>
26)]
27pub async fn get(key: string) {
28    if let Ok(map) = map.recv_one_as::<Arc<StringMap>>().await {
29        let _ = value.send_one_as(map.map.get(&key).cloned()).await;
30    }
31}
32
33/// Receive one `base` map and one `value` block, insert `key` → `value` into a copy of `base`, and emit the updated map on `map`.
34#[mel_treatment(
35    input base Block<StringMap>
36    input value Block<string>
37    output map Block<StringMap>
38)]
39pub async fn insert(key: string) {
40    if let (Ok(base), Ok(value)) = (
41        base.recv_one_as::<Arc<StringMap>>().await,
42        value.recv_one_as::<String>().await,
43    ) {
44        let mut new_map = Arc::unwrap_or_clone(base);
45        new_map.map.insert(key.clone(), value);
46        let _ = map.send_one(Value::Data(Arc::new(new_map))).await;
47    }
48}
49
50/// Merge two maps
51///
52/// Merge map `entries` in `base`.
53/// `entries` erase existing entries in `base` if they already exists.
54/// `entries` can be omitted (closed input) and `merge` will still be emitted if `base` is received.
55#[mel_treatment(
56    input base Block<StringMap>
57    input entries Block<StringMap>
58    output merged Block<StringMap>
59)]
60pub async fn merge() {
61    if let Ok(base) = base.recv_one_as::<Arc<StringMap>>().await {
62        if let Ok(entries) = entries.recv_one_as::<Arc<StringMap>>().await {
63            let mut new_map = Arc::unwrap_or_clone(base);
64            for (key, value) in &entries.map {
65                new_map.map.insert(key.clone(), value.clone());
66            }
67
68            let _ = merged.send_one(Value::Data(Arc::new(new_map))).await;
69        } else {
70            let _ = merged.send_one(Value::Data(base)).await;
71        }
72    }
73}