dataflow_rs/engine/
workflow.rs

1use crate::engine::error::{DataflowError, Result};
2use crate::engine::task::Task;
3use serde::Deserialize;
4use serde_json::Value;
5use std::fs;
6use std::path::Path;
7
8#[derive(Deserialize, Clone, Debug)]
9pub struct Workflow {
10    pub id: String,
11    pub name: String,
12    pub priority: u32,
13    pub description: Option<String>,
14    pub condition: Option<Value>,
15    pub tasks: Vec<Task>,
16}
17
18impl Default for Workflow {
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24impl Workflow {
25    pub fn new() -> Self {
26        Workflow {
27            id: String::new(),
28            name: String::new(),
29            priority: 0,
30            description: None,
31            condition: None,
32            tasks: Vec::new(),
33        }
34    }
35
36    /// Load workflow from JSON string
37    pub fn from_json(json_str: &str) -> Result<Self> {
38        serde_json::from_str(json_str).map_err(DataflowError::from_serde)
39    }
40
41    /// Load workflow from JSON file
42    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
43        let json_str = fs::read_to_string(path).map_err(DataflowError::from_io)?;
44
45        Self::from_json(&json_str)
46    }
47
48    /// Validate the workflow structure
49    pub fn validate(&self) -> Result<()> {
50        // Check required fields
51        if self.id.is_empty() {
52            return Err(DataflowError::Workflow(
53                "Workflow id cannot be empty".to_string(),
54            ));
55        }
56
57        if self.name.is_empty() {
58            return Err(DataflowError::Workflow(
59                "Workflow name cannot be empty".to_string(),
60            ));
61        }
62
63        // Check tasks
64        if self.tasks.is_empty() {
65            return Err(DataflowError::Workflow(
66                "Workflow must have at least one task".to_string(),
67            ));
68        }
69
70        // Validate that task IDs are unique
71        let mut task_ids = std::collections::HashSet::new();
72        for task in &self.tasks {
73            if !task_ids.insert(&task.id) {
74                return Err(DataflowError::Workflow(format!(
75                    "Duplicate task ID '{}' in workflow",
76                    task.id
77                )));
78            }
79        }
80
81        Ok(())
82    }
83}