std_mel/data/map/
mod.rs

1use melodium_core::{executive::*, *};
2use melodium_macro::{check, mel_data, mel_function, mel_treatment};
3use std::collections::HashMap;
4use std::sync::Arc;
5
6pub mod block;
7
8#[mel_data(
9    traits (PartialEquality Serialize Display)
10)]
11#[derive(Clone, Debug, PartialEq, Serialize)]
12pub struct Map {
13    pub map: HashMap<String, Value>,
14}
15
16impl Map {
17    pub fn new() -> Self {
18        Self {
19            map: HashMap::new(),
20        }
21    }
22
23    pub fn new_with(map: HashMap<String, Value>) -> Self {
24        Self { map }
25    }
26}
27
28impl Display for Map {
29    fn display(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
30        write!(f, "{:#?}", self)
31    }
32}
33
34/// Create a map from entries
35#[mel_function]
36pub fn map(entries: Vec<Map>) -> Map {
37    let mut map = HashMap::new();
38    for submap in entries {
39        map.extend(submap.map);
40    }
41    Map { map }
42}
43
44/// Create a map with one entry
45#[mel_function(
46    generic T ()
47)]
48pub fn entry(key: string, value: T) -> Map {
49    let mut map = HashMap::new();
50    map.insert(key, value);
51    Map { map }
52}
53
54/// Create maps with one entry
55///
56/// For every `value` coming through the stream, send a mono-entry map.
57#[mel_treatment(
58    generic T ()
59    input value Stream<T>
60    output map Stream<Map>
61)]
62pub async fn entry(key: string) {
63    while let Ok(value) = value.recv_one().await {
64        let mut new_map = HashMap::new();
65        new_map.insert(key.clone(), value);
66        let new_map = Map { map: new_map };
67        check!(map.send_one(Value::Data(Arc::new(new_map))).await)
68    }
69}
70
71/// Get a map entry
72#[mel_function(
73    generic T ()
74)]
75pub fn get(map: Map, key: string) -> Option<T> {
76    generics
77        .get("T")
78        .map(|dt| map.map.get(&key).cloned().filter(|v| &v.datatype() == dt))
79        .flatten()
80}
81
82/// Get a map entry
83///
84/// For every `map` coming through the stream, get the `key` entry.
85#[mel_treatment(
86    generic T ()
87    input map Stream<Map>
88    output value Stream<Option<T>>
89)]
90pub async fn get(key: string) {
91    while let Ok(map) = map.recv_one().await.map(|val| {
92        GetData::<Arc<dyn Data>>::try_data(val)
93            .unwrap()
94            .downcast_arc::<Map>()
95            .unwrap()
96    }) {
97        check!(value.send_one(map.map.get(&key).cloned().into()).await)
98    }
99}
100
101/// Insert one entry in a map
102#[mel_function(
103    generic T ()
104)]
105pub fn insert(mut map: Map, key: string, value: T) -> Map {
106    map.map.insert(key, value);
107    map
108}
109
110/// Insert entry in map
111///
112/// For every `value` coming through the stream, insert it into the `base` map.
113#[mel_treatment(
114    generic T ()
115    input base Stream<Map>
116    input value Stream<T>
117    output map Stream<Map>
118)]
119pub async fn insert(key: string) {
120    while let (Ok(base), Ok(value)) = (
121        base.recv_one().await.map(|val| {
122            GetData::<Arc<dyn Data>>::try_data(val)
123                .unwrap()
124                .downcast_arc::<Map>()
125                .unwrap()
126        }),
127        value.recv_one().await,
128    ) {
129        let mut new_map = Arc::unwrap_or_clone(base);
130        new_map.map.insert(key.clone(), value);
131        check!(map.send_one(Value::Data(Arc::new(new_map))).await)
132    }
133}