rustfs_rsc/client/
querymap.rs

1use crate::utils::{is_urlencoded, urlencode};
2
3#[derive(Default, Clone, Debug)]
4pub struct QueryMap(Vec<(String, String)>);
5
6impl QueryMap {
7    pub fn new() -> Self {
8        Self(Vec::new())
9    }
10
11    pub fn from_str(query_str: &str) -> Self {
12        let mut qm = Self::new();
13        qm.merge_str(query_str);
14        qm
15    }
16
17    pub fn insert(&mut self, key: String, value: String) {
18        self.0.push((key, value))
19    }
20
21    pub fn merge(&mut self, querys: Self) {
22        self.0.extend(querys.0);
23    }
24
25    pub fn merge_str(&mut self, query_str: &str) {
26        for query in query_str.split("&").filter(|x| !x.is_empty()) {
27            let index = query.find("=");
28            if let Some(i) = index {
29                self.insert(query[0..i].to_string(), query[i + 1..].to_string());
30            } else {
31                self.insert(query.to_string(), "".to_string());
32            }
33        }
34    }
35
36    /// sort query by key
37    pub fn sort(&mut self) {
38        self.0.sort_by(|x, y| x.0.cmp(&y.0));
39    }
40
41    /// get query string.
42    /// the empty keys will be skipped.
43    /// key and value will be uri encode.
44    #[inline]
45    pub fn to_query_string(self) -> String {
46        self.0
47            .iter()
48            .filter(|(k, _)| !k.is_empty())
49            .map(|(k, v)| {
50                let k = if !is_urlencoded(k) {
51                    urlencode(k, false)
52                } else {
53                    k.to_owned()
54                };
55                let v = if !is_urlencoded(v) {
56                    urlencode(v, false)
57                } else {
58                    v.to_owned()
59                };
60                if v.is_empty() {
61                    k
62                } else {
63                    format!("{k}={v}")
64                }
65            })
66            .collect::<Vec<String>>()
67            .join("&")
68    }
69}
70
71impl Into<String> for QueryMap {
72    fn into(self) -> String {
73        self.to_query_string()
74    }
75}