use std::collections::HashMap;
use serde_json::Value as JsonValue;
use crate::channels::Channel;
use crate::constants::{START, RESUME, TASKS};
use crate::types::{Command, CommandGoto};
pub fn map_input(
input_channels: &[String],
input: &JsonValue,
) -> Vec<(String, JsonValue)> {
if let Some(obj) = input.as_object() {
input_channels
.iter()
.filter_map(|ch| {
obj.get(ch).map(|v| (ch.clone(), v.clone()))
})
.collect()
} else {
input_channels
.iter()
.map(|ch| (ch.clone(), input.clone()))
.collect()
}
}
pub fn read_channels(
channels: &HashMap<String, Box<dyn Channel>>,
output_channels: &[String],
) -> JsonValue {
let mut map = serde_json::Map::new();
for ch_name in output_channels {
if let Some(ch) = channels.get(ch_name) {
if let Ok(val) = ch.get() {
map.insert(ch_name.clone(), val);
}
}
}
JsonValue::Object(map)
}
pub fn read_single_channel(
channels: &HashMap<String, Box<dyn Channel>>,
channel_name: &str,
) -> Option<JsonValue> {
channels.get(channel_name)?.get().ok()
}
pub fn map_output_updates(
tasks: &[(String, Vec<(String, JsonValue)>)],
) -> HashMap<String, JsonValue> {
let mut updates = HashMap::new();
for (task_name, writes) in tasks {
let mut map = serde_json::Map::new();
for (chan, val) in writes {
map.insert(chan.clone(), val.clone());
}
updates.insert(task_name.clone(), JsonValue::Object(map));
}
updates
}
pub const NULL_TASK_ID: &str = "00000000-0000-0000-0000-000000000000";
pub fn map_command(cmd: &Command) -> Vec<(String, String, JsonValue)> {
let mut writes = Vec::new();
for goto in &cmd.goto {
match goto {
CommandGoto::Node(name) => {
writes.push((
NULL_TASK_ID.to_string(),
format!("branch:to:{}", name),
JsonValue::String(START.to_string()),
));
}
CommandGoto::Send(send) => {
writes.push((
NULL_TASK_ID.to_string(),
TASKS.to_string(),
serde_json::to_value(send).unwrap_or_default(),
));
}
}
}
if let Some(ref resume) = cmd.resume {
writes.push((
NULL_TASK_ID.to_string(),
RESUME.to_string(),
resume.clone(),
));
}
if let Some(ref update) = cmd.update {
if let Some(obj) = update.as_object() {
for (k, v) in obj {
writes.push((
NULL_TASK_ID.to_string(),
k.clone(),
v.clone(),
));
}
}
}
writes
}