taskflow_rs/executor/handlers/
shell.rs

1use async_trait::async_trait;
2use std::collections::HashMap;
3
4use crate::TaskResult;
5use crate::error::{Result, TaskFlowError};
6use crate::task::{Task, TaskHandler};
7
8pub struct ShellTaskHandler;
9
10impl ShellTaskHandler {
11    pub fn new() -> Self {
12        Self
13    }
14}
15
16#[async_trait]
17impl TaskHandler for ShellTaskHandler {
18    async fn execute(&self, task: &Task) -> Result<TaskResult> {
19        let start_time = std::time::Instant::now();
20
21        let command = task
22            .definition
23            .payload
24            .get("command")
25            .and_then(|v| v.as_str())
26            .ok_or_else(|| {
27                TaskFlowError::InvalidConfiguration("Missing 'command' in payload".to_string())
28            })?;
29
30        let args: Vec<&str> = task
31            .definition
32            .payload
33            .get("args")
34            .and_then(|v| v.as_array())
35            .map(|arr| arr.iter().filter_map(|v| v.as_str()).collect())
36            .unwrap_or_default();
37
38        let output = tokio::process::Command::new(command)
39            .args(&args)
40            .output()
41            .await
42            .map_err(|e| TaskFlowError::ExecutionError(e.to_string()))?;
43
44        let execution_time = start_time.elapsed().as_millis() as u64;
45        let success = output.status.success();
46
47        let stdout = String::from_utf8_lossy(&output.stdout).to_string();
48        let stderr = String::from_utf8_lossy(&output.stderr).to_string();
49
50        let mut metadata = HashMap::new();
51        metadata.insert(
52            "exit_code".to_string(),
53            output.status.code().unwrap_or(-1).to_string(),
54        );
55
56        Ok(TaskResult {
57            success,
58            output: Some(stdout),
59            error: if success { None } else { Some(stderr) },
60            execution_time_ms: execution_time,
61            metadata,
62        })
63    }
64
65    fn task_type(&self) -> &str {
66        "shell_command"
67    }
68}