Skip to main content

pick/
output.rs

1use serde_json::Value;
2
3pub fn format_output(results: &[Value], as_json: bool, as_lines: bool) -> String {
4    if results.is_empty() {
5        return String::new();
6    }
7
8    if as_json {
9        if results.len() == 1 {
10            return serde_json::to_string_pretty(&results[0]).unwrap();
11        }
12        let arr = Value::Array(results.to_vec());
13        return serde_json::to_string_pretty(&arr).unwrap();
14    }
15
16    if as_lines {
17        // Flatten: if results contain arrays, expand them
18        let mut all_values = Vec::new();
19        for r in results {
20            if let Value::Array(arr) = r {
21                all_values.extend(arr.iter().cloned());
22            } else {
23                all_values.push(r.clone());
24            }
25        }
26        return all_values
27            .iter()
28            .map(format_value_plain)
29            .collect::<Vec<_>>()
30            .join("\n");
31    }
32
33    if results.len() == 1 {
34        return format_value_plain(&results[0]);
35    }
36
37    // Multiple results: one per line
38    results
39        .iter()
40        .map(format_value_plain)
41        .collect::<Vec<_>>()
42        .join("\n")
43}
44
45fn format_value_plain(value: &Value) -> String {
46    match value {
47        Value::Null => "null".to_string(),
48        Value::Bool(b) => b.to_string(),
49        Value::Number(n) => n.to_string(),
50        Value::String(s) => s.clone(),
51        // Complex types rendered as compact JSON
52        Value::Array(_) | Value::Object(_) => serde_json::to_string_pretty(value).unwrap(),
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use serde_json::json;
60
61    #[test]
62    fn format_single_string() {
63        assert_eq!(format_output(&[json!("hello")], false, false), "hello");
64    }
65
66    #[test]
67    fn format_single_number() {
68        assert_eq!(format_output(&[json!(42)], false, false), "42");
69    }
70
71    #[test]
72    fn format_single_bool() {
73        assert_eq!(format_output(&[json!(true)], false, false), "true");
74    }
75
76    #[test]
77    fn format_single_null() {
78        assert_eq!(format_output(&[json!(null)], false, false), "null");
79    }
80
81    #[test]
82    fn format_single_float() {
83        let output = format_output(&[json!(3.14)], false, false);
84        assert!(output.starts_with("3.14"));
85    }
86
87    #[test]
88    fn format_object_plain() {
89        let output = format_output(&[json!({"a": 1})], false, false);
90        assert!(output.contains("\"a\""));
91        assert!(output.contains("1"));
92    }
93
94    #[test]
95    fn format_array_plain() {
96        let output = format_output(&[json!([1, 2, 3])], false, false);
97        assert!(output.contains("1"));
98    }
99
100    #[test]
101    fn format_multiple_results() {
102        let output = format_output(&[json!("a"), json!("b"), json!("c")], false, false);
103        assert_eq!(output, "a\nb\nc");
104    }
105
106    #[test]
107    fn format_json_single() {
108        let output = format_output(&[json!("hello")], true, false);
109        assert_eq!(output, "\"hello\"");
110    }
111
112    #[test]
113    fn format_json_number() {
114        let output = format_output(&[json!(42)], true, false);
115        assert_eq!(output, "42");
116    }
117
118    #[test]
119    fn format_json_multiple() {
120        let output = format_output(&[json!("a"), json!("b")], true, false);
121        assert!(output.contains('['));
122        assert!(output.contains("\"a\""));
123    }
124
125    #[test]
126    fn format_lines_array() {
127        let output = format_output(&[json!(["a", "b", "c"])], false, true);
128        assert_eq!(output, "a\nb\nc");
129    }
130
131    #[test]
132    fn format_lines_multiple() {
133        let output = format_output(&[json!("x"), json!("y")], false, true);
134        assert_eq!(output, "x\ny");
135    }
136
137    #[test]
138    fn format_empty() {
139        assert_eq!(format_output(&[], false, false), "");
140    }
141
142    #[test]
143    fn format_empty_string() {
144        assert_eq!(format_output(&[json!("")], false, false), "");
145    }
146
147    #[test]
148    fn format_string_with_newlines() {
149        assert_eq!(
150            format_output(&[json!("line1\nline2")], false, false),
151            "line1\nline2"
152        );
153    }
154}