ironflow-orchestrator 0.1.0

A lightning-fast, zero-dependency workflow orchestrator written in Rust
Documentation
use super::Operator;
use async_trait::async_trait;
use serde_json::Value;
use anyhow::Result;
use std::process::Stdio;
use tokio::process::Command;

pub struct BashOperator;

#[async_trait]
impl Operator for BashOperator {
    async fn execute(&self, config: &Value) -> Result<String> {
        let command = config
            .get("command")
            .and_then(|v| v.as_str())
            .ok_or_else(|| anyhow::anyhow!("Missing 'command' field in bash operator config"))?;

        let output = Command::new("bash")
            .arg("-c")
            .arg(command)
            .stdout(Stdio::piped())
            .stderr(Stdio::piped())
            .output()
            .await?;

        let stdout = String::from_utf8_lossy(&output.stdout).to_string();
        let stderr = String::from_utf8_lossy(&output.stderr).to_string();

        if !output.status.success() {
            return Err(anyhow::anyhow!(
                "Bash command failed with exit code: {:?}\nStderr: {}",
                output.status.code(),
                stderr
            ));
        }

        Ok(stdout)
    }

    fn name(&self) -> &'static str {
        "bash"
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn test_bash_operator_success() {
        let config = serde_json::json!({
            "command": "echo 'hello world'"
        });

        let operator = BashOperator;
        let result = operator.execute(&config).await;
        assert!(result.is_ok());
        assert!(result.unwrap().contains("hello world"));
    }

    #[tokio::test]
    async fn test_bash_operator_failure() {
        let config = serde_json::json!({
            "command": "exit 1"
        });

        let operator = BashOperator;
        let result = operator.execute(&config).await;
        assert!(result.is_err());
    }

    #[tokio::test]
    async fn test_bash_operator_missing_command() {
        let config = serde_json::json!({});

        let operator = BashOperator;
        let result = operator.execute(&config).await;
        assert!(result.is_err());
    }
}