1use std::collections::{HashMap, HashSet};
4
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use uuid::Uuid;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct FlowResult {
19 pub execution_id: Uuid,
21 pub outputs: HashMap<String, Value>,
27 pub completed_nodes: HashSet<String>,
29 pub skipped_nodes: HashSet<String>,
31 #[serde(default)]
36 pub context: HashMap<String, Value>,
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use serde_json::json;
43
44 #[test]
45 fn serialize_deserialize_round_trip() {
46 let original = FlowResult {
47 execution_id: Uuid::new_v4(),
48 outputs: HashMap::from([
49 ("a".into(), json!({ "ok": true })),
50 ("b".into(), json!(null)),
51 ]),
52 completed_nodes: HashSet::from(["a".into(), "b".into()]),
53 skipped_nodes: HashSet::from(["b".into()]),
54 context: HashMap::from([("k".into(), json!("v"))]),
55 };
56
57 let json_str = serde_json::to_string(&original).expect("serialize");
58 let restored: FlowResult = serde_json::from_str(&json_str).expect("deserialize");
59
60 assert_eq!(restored.execution_id, original.execution_id);
61 assert_eq!(restored.outputs, original.outputs);
62 assert_eq!(restored.completed_nodes, original.completed_nodes);
63 assert_eq!(restored.skipped_nodes, original.skipped_nodes);
64 assert_eq!(restored.context, original.context);
65 }
66
67 #[test]
68 fn context_defaults_to_empty_on_deserialize() {
69 let json_str = r#"{"execution_id":"00000000-0000-0000-0000-000000000000","outputs":{},"completed_nodes":[],"skipped_nodes":[]}"#;
71 let result: FlowResult = serde_json::from_str(json_str).expect("deserialize");
72 assert!(result.context.is_empty());
73 }
74}