Skip to main content

romm_cli/endpoints/
roms.rs

1use crate::types::RomList;
2
3use super::Endpoint;
4
5/// Retrieve ROMs with optional filters.
6#[derive(Debug, Default, Clone)]
7pub struct GetRoms {
8    pub search_term: Option<String>,
9    pub platform_id: Option<u64>,
10    /// Manual collection filter (`GET /api/roms?collection_id=`).
11    pub collection_id: Option<u64>,
12    /// Smart collection filter (`GET /api/roms?smart_collection_id=`).
13    pub smart_collection_id: Option<u64>,
14    /// Virtual (autogenerated) collection filter (`GET /api/roms?virtual_collection_id=`).
15    pub virtual_collection_id: Option<String>,
16    pub limit: Option<u32>,
17    pub offset: Option<u32>,
18}
19
20impl Endpoint for GetRoms {
21    type Output = RomList;
22
23    fn method(&self) -> &'static str {
24        "GET"
25    }
26
27    fn path(&self) -> String {
28        "/api/roms".into()
29    }
30
31    fn query(&self) -> Vec<(String, String)> {
32        let mut q = Vec::new();
33
34        if let Some(term) = &self.search_term {
35            q.push(("search_term".into(), term.clone()));
36        }
37
38        // RomM API expects "platform_ids" (plural); repeat param for multiple values.
39        if let Some(pid) = self.platform_id {
40            q.push(("platform_ids".into(), pid.to_string()));
41        }
42
43        if let Some(cid) = self.collection_id {
44            q.push(("collection_id".into(), cid.to_string()));
45        }
46
47        if let Some(sid) = self.smart_collection_id {
48            q.push(("smart_collection_id".into(), sid.to_string()));
49        }
50
51        if let Some(ref vid) = self.virtual_collection_id {
52            q.push(("virtual_collection_id".into(), vid.clone()));
53        }
54
55        if let Some(limit) = self.limit {
56            q.push(("limit".into(), limit.to_string()));
57        }
58
59        if let Some(offset) = self.offset {
60            q.push(("offset".into(), offset.to_string()));
61        }
62
63        q
64    }
65}
66
67/// Retrieve a single ROM by ID.
68#[derive(Debug, Clone)]
69pub struct GetRom {
70    pub id: u64,
71}
72
73impl Endpoint for GetRom {
74    type Output = crate::types::Rom;
75
76    fn method(&self) -> &'static str {
77        "GET"
78    }
79
80    fn path(&self) -> String {
81        format!("/api/roms/{}", self.id)
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::{Endpoint, GetRoms};
88
89    #[test]
90    fn get_roms_query_sends_collection_id() {
91        let ep = GetRoms {
92            collection_id: Some(7),
93            limit: Some(100),
94            ..Default::default()
95        };
96        let q = ep.query();
97        assert!(q.iter().any(|(k, v)| k == "collection_id" && v == "7"));
98        assert!(!q.iter().any(|(k, _)| k == "smart_collection_id"));
99    }
100
101    #[test]
102    fn get_roms_query_sends_smart_collection_id() {
103        let ep = GetRoms {
104            smart_collection_id: Some(3),
105            limit: Some(50),
106            ..Default::default()
107        };
108        let q = ep.query();
109        assert!(q
110            .iter()
111            .any(|(k, v)| k == "smart_collection_id" && v == "3"));
112        assert!(!q.iter().any(|(k, _)| k == "collection_id"));
113        assert!(!q.iter().any(|(k, _)| k == "virtual_collection_id"));
114    }
115
116    #[test]
117    fn get_roms_query_sends_virtual_collection_id() {
118        let ep = GetRoms {
119            virtual_collection_id: Some("recent".into()),
120            limit: Some(10),
121            ..Default::default()
122        };
123        let q = ep.query();
124        assert!(q
125            .iter()
126            .any(|(k, v)| k == "virtual_collection_id" && v == "recent"));
127        assert!(!q.iter().any(|(k, _)| k == "collection_id"));
128    }
129}