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}