pub mod message_send;
pub mod state;
pub mod trigger;
#[cfg(test)]
mod tests;
use serde_json::Value;
use crate::pipeline::PipelineError;
use crate::pipeline::model::{DslFlag, DslFlagKind, NodeFieldDef, NodeFieldType};
use crate::pipeline::nodes::NodeExecutionOutput;
use crate::pipeline::nodes::shared::util::with_answer;
use crate::pipeline::NodeDefinition;
const INPUT_PIN_IN: &str = "in";
const OUTPUT_PIN_OUT: &str = "out";
pub fn definitions() -> Vec<NodeDefinition> {
vec![
trigger::definition(),
message_send::definition(),
state::definition(state::Verb::Put),
state::definition(state::Verb::Update),
state::definition(state::Verb::Delete),
]
}
fn flag(name: &str, key: &str, description: &str, value: &str, required: bool) -> DslFlag {
DslFlag {
flag: name.to_string(),
config_key: key.to_string(),
description: description.to_string(),
kind: DslFlagKind::Scalar,
required,
value: value.to_string(),
..Default::default()
}
}
fn field(name: &str, label: &str, help: &str) -> NodeFieldDef {
NodeFieldDef {
name: name.to_string(),
label: label.to_string(),
field_type: NodeFieldType::Text,
help: Some(help.to_string()),
..Default::default()
}
}
fn text_of(value: &Value, flag: &str, code: &'static str) -> Result<String, PipelineError> {
match value {
Value::Null => Ok(String::new()),
Value::String(s) => Ok(s.trim().to_string()),
Value::Number(n) => Ok(n.to_string()),
Value::Bool(b) => Ok(b.to_string()),
_ => Err(PipelineError::new(
code,
format!("{flag} must be text, not a JSON {}", if value.is_array() { "list" } else { "object" }),
)),
}
}
fn room_of(configured: &str, metadata: &Value) -> String {
if !configured.is_empty() {
return configured.to_string();
}
trigger_field(metadata, "room_id")
}
fn trigger_field(metadata: &Value, name: &str) -> String {
crate::pipeline::nodes::basic::trigger::envelope(metadata)
.get(name)
.and_then(Value::as_str)
.unwrap_or_default()
.to_string()
}
fn room_key(metadata: &Value, room: &str) -> String {
let owner = metadata.get("owner").and_then(Value::as_str).unwrap_or_default();
let project = metadata.get("project").and_then(Value::as_str).unwrap_or_default();
format!("{owner}/{project}/{room}")
}
fn answer(payload: &Value, answer: Value, trace: String) -> NodeExecutionOutput {
NodeExecutionOutput {
output_pins: vec![OUTPUT_PIN_OUT.to_string()],
payload: with_answer(payload, answer),
trace: vec![trace],
}
}