spotify_cli/io/formatters/
category.rs

1//! Category formatting functions
2
3use serde_json::Value;
4
5use crate::io::common::print_table;
6
7pub fn format_categories(items: &[Value]) {
8    let rows: Vec<Vec<String>> = items
9        .iter()
10        .enumerate()
11        .map(|(i, cat)| {
12            let name = cat
13                .get("name")
14                .and_then(|v| v.as_str())
15                .unwrap_or("Unknown");
16            let id = cat.get("id").and_then(|v| v.as_str()).unwrap_or("");
17            vec![(i + 1).to_string(), name.to_string(), id.to_string()]
18        })
19        .collect();
20    print_table("Categories", &["#", "Name", "ID"], &rows, &[3, 30, 20]);
21}
22
23pub fn format_category_detail(payload: &Value) {
24    let name = payload
25        .get("name")
26        .and_then(|v| v.as_str())
27        .unwrap_or("Unknown");
28    let id = payload.get("id").and_then(|v| v.as_str()).unwrap_or("");
29
30    println!("{}", name);
31    println!("  ID: {}", id);
32
33    if let Some(icons) = payload.get("icons").and_then(|i| i.as_array())
34        && let Some(first) = icons.first()
35        && let Some(url) = first.get("url").and_then(|v| v.as_str())
36    {
37        println!("  Icon: {}", url);
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44    use serde_json::json;
45
46    #[test]
47    fn format_categories_with_items() {
48        let items = vec![
49            json!({ "name": "Pop", "id": "pop" }),
50            json!({ "name": "Rock", "id": "rock" }),
51            json!({ "name": "Hip-Hop", "id": "hiphop" }),
52        ];
53        format_categories(&items);
54    }
55
56    #[test]
57    fn format_categories_empty() {
58        let items: Vec<Value> = vec![];
59        format_categories(&items);
60    }
61
62    #[test]
63    fn format_categories_minimal() {
64        let items = vec![json!({})];
65        format_categories(&items);
66    }
67
68    #[test]
69    fn format_category_detail_full() {
70        let payload = json!({
71            "name": "Top Lists",
72            "id": "toplists",
73            "icons": [{ "url": "https://example.com/icon.png" }]
74        });
75        format_category_detail(&payload);
76    }
77
78    #[test]
79    fn format_category_detail_minimal() {
80        let payload = json!({});
81        format_category_detail(&payload);
82    }
83
84    #[test]
85    fn format_category_detail_no_icons() {
86        let payload = json!({
87            "name": "Mood",
88            "id": "mood"
89        });
90        format_category_detail(&payload);
91    }
92
93    #[test]
94    fn format_category_detail_empty_icons() {
95        let payload = json!({
96            "name": "Focus",
97            "id": "focus",
98            "icons": []
99        });
100        format_category_detail(&payload);
101    }
102}