1use std::collections::HashMap;
4use std::sync::Arc;
5
6pub type NodeId = usize;
8
9pub type NodeFunction = Arc<dyn Fn(&HashMap<String, String>, &HashMap<String, String>) -> HashMap<String, String> + Send + Sync>;
12
13#[derive(Clone)]
15pub struct Node {
16 pub id: NodeId,
18 pub label: Option<String>,
20 pub function: NodeFunction,
22 pub input_mapping: HashMap<String, String>,
24 pub output_mapping: HashMap<String, String>,
26 pub branch_id: Option<usize>,
28 pub dependencies: Vec<NodeId>,
30 pub is_branch: bool,
32 pub variant_index: Option<usize>,
34 pub variant_params: HashMap<String, String>,
36}
37
38impl Node {
39 pub fn new(
41 id: NodeId,
42 function: NodeFunction,
43 label: Option<String>,
44 input_mapping: HashMap<String, String>,
45 output_mapping: HashMap<String, String>,
46 ) -> Self {
47 Self {
48 id,
49 label,
50 function,
51 input_mapping,
52 output_mapping,
53 branch_id: None,
54 dependencies: Vec::new(),
55 is_branch: false,
56 variant_index: None,
57 variant_params: HashMap::new(),
58 }
59 }
60
61 pub fn execute(&self, context: &HashMap<String, String>) -> HashMap<String, String> {
63 let inputs: HashMap<String, String> = self
66 .input_mapping
67 .iter()
68 .filter_map(|(broadcast_var, impl_var)| {
69 context.get(broadcast_var).map(|val| (impl_var.clone(), val.clone()))
70 })
71 .collect();
72
73 let func_outputs = (self.function)(&inputs, &self.variant_params);
75
76 let mut context_outputs = HashMap::new();
79 for (impl_var, broadcast_var) in &self.output_mapping {
80 if let Some(value) = func_outputs.get(impl_var) {
81 context_outputs.insert(broadcast_var.clone(), value.clone());
82 }
83 }
84
85 context_outputs
86 }
87
88 pub fn display_name(&self) -> String {
90 self.label
91 .as_ref()
92 .map(|l| l.clone())
93 .unwrap_or_else(|| format!("Node {}", self.id))
94 }
95}