Skip to main content

limit_cli/tools/browser/
response.rs

1//! JSON response builder for browser tool
2//!
3//! Provides a fluent builder pattern for constructing JSON responses
4//! with consistent structure across all browser operations.
5
6use serde_json::{json, Value};
7
8/// Builder for constructing JSON responses
9#[derive(Default)]
10pub struct Response {
11    success: bool,
12    message: Option<String>,
13    data: Vec<(&'static str, Value)>,
14}
15
16impl Response {
17    /// Create a successful response
18    pub fn success() -> Self {
19        Self {
20            success: true,
21            ..Default::default()
22        }
23    }
24
25    /// Create a failed response
26    pub fn failure() -> Self {
27        Self {
28            success: false,
29            ..Default::default()
30        }
31    }
32
33    /// Add a message to the response
34    pub fn message(mut self, msg: impl Into<String>) -> Self {
35        self.message = Some(msg.into());
36        self
37    }
38
39    /// Add a key-value data pair
40    pub fn data(mut self, key: &'static str, value: impl Into<Value>) -> Self {
41        self.data.push((key, value.into()));
42        self
43    }
44
45    /// Build the final JSON value
46    pub fn build(self) -> Value {
47        let mut map = serde_json::Map::new();
48        map.insert("success".to_string(), json!(self.success));
49
50        if let Some(msg) = self.message {
51            map.insert("message".to_string(), json!(msg));
52        }
53
54        for (key, value) in self.data {
55            map.insert(key.to_string(), value);
56        }
57
58        Value::Object(map)
59    }
60}
61
62/// Convenience function for simple success with message
63pub fn ok_msg(msg: impl Into<String>) -> Value {
64    Response::success().message(msg).build()
65}
66
67/// Convenience function for simple success without message
68pub fn ok() -> Value {
69    Response::success().build()
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn test_response_success() {
78        let response = Response::success().build();
79        assert_eq!(response["success"], true);
80    }
81
82    #[test]
83    fn test_response_failure() {
84        let response = Response::failure().build();
85        assert_eq!(response["success"], false);
86    }
87
88    #[test]
89    fn test_response_with_message() {
90        let response = Response::success().message("Test message").build();
91        assert_eq!(response["success"], true);
92        assert_eq!(response["message"], "Test message");
93    }
94
95    #[test]
96    fn test_response_with_data() {
97        let response = Response::success()
98            .data("url", "https://example.com")
99            .data("count", 42)
100            .build();
101        assert_eq!(response["success"], true);
102        assert_eq!(response["url"], "https://example.com");
103        assert_eq!(response["count"], 42);
104    }
105
106    #[test]
107    fn test_response_with_message_and_data() {
108        let response = Response::success()
109            .message("Opened page")
110            .data("url", "https://example.com")
111            .data("title", "Example Page")
112            .build();
113        assert_eq!(response["success"], true);
114        assert_eq!(response["message"], "Opened page");
115        assert_eq!(response["url"], "https://example.com");
116        assert_eq!(response["title"], "Example Page");
117    }
118
119    #[test]
120    fn test_ok_msg() {
121        let response = ok_msg("Test message");
122        assert_eq!(response["success"], true);
123        assert_eq!(response["message"], "Test message");
124    }
125
126    #[test]
127    fn test_ok() {
128        let response = ok();
129        assert_eq!(response["success"], true);
130        assert!(!response.as_object().unwrap().contains_key("message"));
131    }
132
133    #[test]
134    fn test_response_builder_chain() {
135        let response = Response::success()
136            .message("Snapshot taken")
137            .data("content", "<html>...</html>")
138            .data("title", "Test Page")
139            .data("url", "https://example.com")
140            .build();
141
142        assert_eq!(response["success"], true);
143        assert_eq!(response["message"], "Snapshot taken");
144        assert_eq!(response["content"], "<html>...</html>");
145        assert_eq!(response["title"], "Test Page");
146        assert_eq!(response["url"], "https://example.com");
147    }
148}