Skip to main content

ironflow_engine/config/
http.rs

1//! [`HttpConfig`] — serializable configuration for an HTTP step.
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6/// Serializable configuration for an HTTP step.
7///
8/// # Examples
9///
10/// ```
11/// use ironflow_engine::config::HttpConfig;
12///
13/// let config = HttpConfig::get("https://api.example.com/health");
14/// ```
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct HttpConfig {
17    /// HTTP method (GET, POST, PUT, PATCH, DELETE).
18    pub method: String,
19    /// Request URL.
20    pub url: String,
21    /// Request headers.
22    pub headers: Vec<(String, String)>,
23    /// Request body as JSON.
24    pub body: Option<Value>,
25    /// Timeout in seconds (default: 30).
26    pub timeout_secs: Option<u64>,
27}
28
29impl HttpConfig {
30    /// Create a GET request config.
31    ///
32    /// # Examples
33    ///
34    /// ```
35    /// use ironflow_engine::config::HttpConfig;
36    ///
37    /// let config = HttpConfig::get("https://example.com");
38    /// assert_eq!(config.method, "GET");
39    /// ```
40    pub fn get(url: &str) -> Self {
41        Self::new("GET", url)
42    }
43
44    /// Create a POST request config.
45    pub fn post(url: &str) -> Self {
46        Self::new("POST", url)
47    }
48
49    /// Create a PUT request config.
50    pub fn put(url: &str) -> Self {
51        Self::new("PUT", url)
52    }
53
54    /// Create a PATCH request config.
55    pub fn patch(url: &str) -> Self {
56        Self::new("PATCH", url)
57    }
58
59    /// Create a DELETE request config.
60    pub fn delete(url: &str) -> Self {
61        Self::new("DELETE", url)
62    }
63
64    fn new(method: &str, url: &str) -> Self {
65        Self {
66            method: method.to_string(),
67            url: url.to_string(),
68            headers: Vec::new(),
69            body: None,
70            timeout_secs: None,
71        }
72    }
73
74    /// Add a request header.
75    pub fn header(mut self, name: &str, value: &str) -> Self {
76        self.headers.push((name.to_string(), value.to_string()));
77        self
78    }
79
80    /// Set the request body as JSON.
81    pub fn json(mut self, body: Value) -> Self {
82        self.body = Some(body);
83        self
84    }
85
86    /// Set the timeout in seconds.
87    pub fn timeout_secs(mut self, secs: u64) -> Self {
88        self.timeout_secs = Some(secs);
89        self
90    }
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96    use serde_json::json;
97
98    #[test]
99    fn methods() {
100        assert_eq!(HttpConfig::get("http://x").method, "GET");
101        assert_eq!(HttpConfig::post("http://x").method, "POST");
102        assert_eq!(HttpConfig::put("http://x").method, "PUT");
103        assert_eq!(HttpConfig::patch("http://x").method, "PATCH");
104        assert_eq!(HttpConfig::delete("http://x").method, "DELETE");
105    }
106
107    #[test]
108    fn builder() {
109        let config = HttpConfig::post("http://api.example.com")
110            .header("Authorization", "Bearer token")
111            .json(json!({"key": "value"}))
112            .timeout_secs(10);
113
114        assert_eq!(config.headers.len(), 1);
115        assert!(config.body.is_some());
116        assert_eq!(config.timeout_secs, Some(10));
117    }
118}