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