greentic_flow/add_step/
modes.rs

1use std::path::Path;
2
3use serde_json::{Map, Value, json};
4
5use crate::{
6    component_catalog::ComponentCatalog, config_flow::run_config_flow, error::Result,
7    loader::load_ygtc_from_str_with_schema,
8};
9
10use super::normalize::normalize_node_map;
11
12#[derive(Debug, Clone)]
13pub enum AddStepModeInput {
14    Default {
15        operation: String,
16        payload: Value,
17        routing: Option<Value>,
18    },
19    Config {
20        config_flow: String,
21        schema_path: Box<Path>,
22        answers: Map<String, Value>,
23    },
24}
25
26pub fn materialize_node(
27    mode: AddStepModeInput,
28    _catalog: &dyn ComponentCatalog,
29) -> Result<(Option<String>, Value)> {
30    match mode {
31        AddStepModeInput::Default {
32            operation,
33            payload,
34            routing,
35        } => {
36            let mut node = serde_json::Map::new();
37            node.insert(operation.clone(), payload);
38            if let Some(routing) = routing {
39                node.insert("routing".to_string(), routing);
40            } else {
41                node.insert(
42                    "routing".to_string(),
43                    json!([{ "to": crate::splice::NEXT_NODE_PLACEHOLDER }]),
44                );
45            }
46            let value = Value::Object(node.clone());
47            // Ensure shape is valid up front.
48            let normalized = normalize_node_map(value.clone())?;
49            Ok((Some(normalized.operation.clone()), Value::Object(node)))
50        }
51        AddStepModeInput::Config {
52            config_flow,
53            schema_path,
54            answers,
55        } => {
56            let _doc = load_ygtc_from_str_with_schema(&config_flow, &schema_path)?; // schema validation
57            let output = run_config_flow(&config_flow, &schema_path, &answers)?;
58            let normalized = normalize_node_map(output.node.clone())?;
59            let mut hint = Some(output.node_id.clone());
60            if normalized.operation.is_empty() {
61                hint = None;
62            }
63            Ok((hint, output.node))
64        }
65    }
66}