lastfm_client/
url_builder.rs1use std::collections::HashMap;
2
3pub type QueryParams = HashMap<String, String>;
5
6#[derive(Debug, Clone)]
8pub struct Url {
9 base: String,
10 query_params: QueryParams,
11}
12
13impl Url {
14 #[must_use]
16 pub fn new(base: &str) -> Self {
17 Self {
18 base: base.to_string(),
19 query_params: HashMap::new(),
20 }
21 }
22
23 #[must_use]
25 pub fn add_args(mut self, args: QueryParams) -> Self {
26 self.query_params.extend(args);
27
28 self
29 }
30
31 #[must_use]
33 pub fn build(&self) -> String {
34 if self.query_params.is_empty() {
35 return self.base.clone();
36 }
37
38 let query_string: Vec<String> = self
39 .query_params
40 .iter()
41 .map(|(k, v)| format!("{k}={v}"))
42 .collect();
43
44 format!("{}?{}", self.base, query_string.join("&"))
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn test_basic_url() {
54 let url = Url::new("https://www.google.com");
55 assert_eq!(url.build(), "https://www.google.com");
56 }
57
58 #[test]
59 fn test_single_query_param() {
60 let mut params = HashMap::new();
61 params.insert("q".to_string(), "rust".to_string());
62
63 let url = Url::new("https://www.google.com").add_args(params);
64 assert_eq!(url.build(), "https://www.google.com?q=rust");
65 }
66
67 #[test]
68 fn test_multiple_query_params() {
69 let mut params = HashMap::new();
70 params.insert("q".to_string(), "rust".to_string());
71 params.insert("lang".to_string(), "en".to_string());
72
73 let url = Url::new("https://www.google.com").add_args(params);
74 let built_url = url.build();
75 assert!(
76 built_url == "https://www.google.com?q=rust&lang=en"
77 || built_url == "https://www.google.com?lang=en&q=rust"
78 );
79 }
80
81 #[test]
82 fn test_chained_param_addition() {
83 let url = Url::new("https://www.example.com")
84 .add_args(HashMap::from([("page".to_string(), "1".to_string())]))
85 .add_args(HashMap::from([("limit".to_string(), "10".to_string())]));
86
87 let built_url = url.build();
88 assert!(
89 built_url == "https://www.example.com?page=1&limit=10"
90 || built_url == "https://www.example.com?limit=10&page=1"
91 );
92 }
93
94 #[test]
95 fn test_param_overwrite() {
96 let mut params1 = HashMap::new();
97 params1.insert("key".to_string(), "value1".to_string());
98
99 let mut params2 = HashMap::new();
100 params2.insert("key".to_string(), "value2".to_string());
101
102 let url = Url::new("https://www.example.com")
103 .add_args(params1)
104 .add_args(params2);
105
106 assert_eq!(url.build(), "https://www.example.com?key=value2");
107 }
108}