indodax_cli/output/
json.rs1use super::CommandOutput;
2
3pub fn render(output: &CommandOutput) -> String {
4 let mut envelope = serde_json::json!({
5 "success": true,
6 "data": output.data,
7 });
8 if let Some(ref addendum) = output.addendum {
9 envelope["addendum"] = serde_json::Value::String(addendum.clone());
10 }
11 if !output.warnings.is_empty() {
12 envelope["warnings"] = serde_json::Value::Array(
13 output.warnings.iter().map(|w| serde_json::Value::String(w.clone())).collect()
14 );
15 }
16 serde_json::to_string_pretty(&envelope).unwrap_or_else(|_| "{}".into())
17}
18
19#[cfg(test)]
20mod tests {
21 use super::*;
22 use serde_json::json;
23
24 #[test]
25 fn test_render_simple_object() {
26 let output = CommandOutput {
27 data: json!({"key": "value"}),
28 headers: vec![],
29 rows: vec![],
30 format: super::super::OutputFormat::Json,
31 addendum: None,
32 warnings: vec![],
33 suppress_final_output: false,
34 };
35
36 let rendered = render(&output);
37 let parsed: serde_json::Value = serde_json::from_str(&rendered).unwrap();
38 assert_eq!(parsed["data"]["key"], "value");
39 }
40
41 #[test]
42 fn test_render_nested_object() {
43 let output = CommandOutput {
44 data: json!({"nested": {"a": 1, "b": 2}}),
45 headers: vec![],
46 rows: vec![],
47 format: super::super::OutputFormat::Json,
48 addendum: None,
49 warnings: vec![],
50 suppress_final_output: false,
51 };
52
53 let rendered = render(&output);
54 let parsed: serde_json::Value = serde_json::from_str(&rendered).unwrap();
55 assert_eq!(parsed["data"]["nested"]["a"], 1);
56 assert_eq!(parsed["data"]["nested"]["b"], 2);
57 }
58
59 #[test]
60 fn test_render_array() {
61 let output = CommandOutput {
62 data: json!([1, 2, 3]),
63 headers: vec![],
64 rows: vec![],
65 format: super::super::OutputFormat::Json,
66 addendum: None,
67 warnings: vec![],
68 suppress_final_output: false,
69 };
70
71 let rendered = render(&output);
72 let parsed: serde_json::Value = serde_json::from_str(&rendered).unwrap();
73 assert_eq!(parsed["data"][0], 1);
74 assert_eq!(parsed["data"][1], 2);
75 assert_eq!(parsed["data"][2], 3);
76 }
77
78 #[test]
79 fn test_render_empty_object() {
80 let output = CommandOutput {
81 data: json!({}),
82 headers: vec![],
83 rows: vec![],
84 format: super::super::OutputFormat::Json,
85 addendum: None,
86 warnings: vec![],
87 suppress_final_output: false,
88 };
89
90 let rendered = render(&output);
91 let parsed: serde_json::Value = serde_json::from_str(&rendered).unwrap();
92 assert_eq!(parsed["data"], json!({}));
93 }
94
95 #[test]
96 fn test_render_null() {
97 let output = CommandOutput {
98 data: json!(null),
99 headers: vec![],
100 rows: vec![],
101 format: super::super::OutputFormat::Json,
102 addendum: None,
103 warnings: vec![],
104 suppress_final_output: false,
105 };
106
107 let rendered = render(&output);
108 let parsed: serde_json::Value = serde_json::from_str(&rendered).unwrap();
109 assert!(parsed["data"].is_null());
110 }
111
112 #[test]
113 fn test_render_with_special_chars() {
114 let output = CommandOutput {
115 data: json!({"msg": "hello\nworld\t!"}),
116 headers: vec![],
117 rows: vec![],
118 format: super::super::OutputFormat::Json,
119 addendum: None,
120 warnings: vec![],
121 suppress_final_output: false,
122 };
123
124 let rendered = render(&output);
125 let parsed: serde_json::Value = serde_json::from_str(&rendered).unwrap();
126 assert_eq!(parsed["data"]["msg"], "hello\nworld\t!");
127 }
128
129 #[test]
130 fn test_render_with_addendum() {
131 let output = CommandOutput {
132 data: json!({"key": "value"}),
133 headers: vec![],
134 rows: vec![],
135 format: super::super::OutputFormat::Json,
136 addendum: Some("Extra message".into()),
137 warnings: vec![],
138 suppress_final_output: false,
139 };
140
141 let rendered = render(&output);
142 let parsed: serde_json::Value = serde_json::from_str(&rendered).unwrap();
143 assert_eq!(parsed["data"]["key"], "value");
144 assert_eq!(parsed["addendum"], "Extra message");
145 }
146}