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