taskflow-rs 0.1.1

A high-performance, async-first task orchestration framework for Rust
Documentation
use async_trait::async_trait;
use reqwest;
use std::collections::HashMap;

use crate::TaskResult;
use crate::error::{Result, TaskFlowError};
use crate::task::{Task, TaskHandler};

pub struct HttpTaskHandler {
    client: reqwest::Client,
}

impl HttpTaskHandler {
    pub fn new() -> Self {
        Self {
            client: reqwest::Client::new(),
        }
    }
}

#[async_trait]
impl TaskHandler for HttpTaskHandler {
    async fn execute(&self, task: &Task) -> Result<TaskResult> {
        let start_time = std::time::Instant::now();

        let url = task
            .definition
            .payload
            .get("url")
            .and_then(|v| v.as_str())
            .ok_or_else(|| {
                TaskFlowError::InvalidConfiguration("Missing 'url' in payload".to_string())
            })?;

        let method = task
            .definition
            .payload
            .get("method")
            .and_then(|v| v.as_str())
            .unwrap_or("GET");

        let response = match method.to_uppercase().as_str() {
            "GET" => self.client.get(url).send().await?,
            "POST" => {
                let mut request = self.client.post(url);
                if let Some(body) = task.definition.payload.get("body") {
                    request = request.json(body);
                }
                request.send().await?
            }
            _ => {
                return Err(TaskFlowError::InvalidConfiguration(format!(
                    "Unsupported HTTP method: {}",
                    method
                )));
            }
        };

        let status = response.status();
        let body = response.text().await?;
        let execution_time = start_time.elapsed().as_millis() as u64;

        let success = status.is_success();
        let mut metadata = HashMap::new();
        metadata.insert("status_code".to_string(), status.as_u16().to_string());
        metadata.insert("method".to_string(), method.to_string());

        Ok(TaskResult {
            success,
            output: Some(body),
            error: if success {
                None
            } else {
                Some(format!("HTTP {}", status))
            },
            execution_time_ms: execution_time,
            metadata,
        })
    }

    fn task_type(&self) -> &str {
        "http_request"
    }
}