Skip to main content

ironflow_engine/config/
mod.rs

1//! Serializable step configurations — one per operation type.
2//!
3//! These types mirror the builder options in [`ironflow_core`] operations but
4//! are fully serializable, allowing them to be stored as JSON in the database
5//! and reconstructed by the executor at runtime.
6
7mod agent;
8mod approval;
9mod http;
10mod shell;
11mod workflow;
12
13pub use agent::AgentStepConfig;
14pub use approval::ApprovalConfig;
15pub use http::HttpConfig;
16pub use shell::ShellConfig;
17pub use workflow::WorkflowStepConfig;
18
19use ironflow_store::entities::StepKind;
20use serde::{Deserialize, Serialize};
21
22/// A serializable step configuration, wrapping one of the operation-specific configs.
23///
24/// Stored as JSON in the `steps.input` column and reconstructed by the
25/// executor at runtime.
26///
27/// # Examples
28///
29/// ```
30/// use ironflow_engine::config::{StepConfig, ShellConfig};
31///
32/// let config = StepConfig::Shell(ShellConfig::new("echo hello"));
33/// let json = serde_json::to_string(&config).unwrap();
34/// assert!(json.contains("echo hello"));
35/// ```
36#[derive(Debug, Clone, Serialize, Deserialize)]
37#[serde(tag = "type", rename_all = "snake_case")]
38pub enum StepConfig {
39    /// A shell command step.
40    Shell(ShellConfig),
41    /// An HTTP request step.
42    Http(HttpConfig),
43    /// An AI agent step.
44    Agent(AgentStepConfig),
45    /// A sub-workflow invocation step.
46    Workflow(WorkflowStepConfig),
47    /// A human approval gate step.
48    Approval(ApprovalConfig),
49}
50
51impl StepConfig {
52    /// Get the kind of step this configuration represents.
53    ///
54    /// # Examples
55    ///
56    /// ```
57    /// use ironflow_engine::config::{StepConfig, ShellConfig};
58    /// use ironflow_store::entities::StepKind;
59    ///
60    /// let config = StepConfig::Shell(ShellConfig::new("echo test"));
61    /// assert_eq!(config.kind(), StepKind::Shell);
62    /// ```
63    pub fn kind(&self) -> StepKind {
64        match self {
65            StepConfig::Shell(_) => StepKind::Shell,
66            StepConfig::Http(_) => StepKind::Http,
67            StepConfig::Agent(_) => StepKind::Agent,
68            StepConfig::Workflow(_) => StepKind::Workflow,
69            StepConfig::Approval(_) => StepKind::Approval,
70        }
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn serde_roundtrip() {
80        let configs = vec![
81            StepConfig::Shell(ShellConfig::new("echo test")),
82            StepConfig::Http(HttpConfig::get("http://example.com")),
83            StepConfig::Agent(AgentStepConfig::new("summarize")),
84            StepConfig::Workflow(WorkflowStepConfig::new("build", serde_json::json!({}))),
85            StepConfig::Approval(ApprovalConfig::new("Deploy to production?")),
86        ];
87
88        for config in configs {
89            let json = serde_json::to_string(&config).expect("serialize");
90            let back: StepConfig = serde_json::from_str(&json).expect("deserialize");
91            let json2 = serde_json::to_string(&back).expect("serialize2");
92            assert_eq!(json, json2);
93        }
94    }
95}