1use crate::params::{IdSite, Limit, Period, Segment};
2
3#[derive(Debug, Clone, Default, PartialEq, Eq)]
10pub struct Params {
11 fields: Vec<(String, String)>,
12}
13
14impl Params {
15 pub fn new() -> Self {
16 Params::default()
17 }
18
19 pub fn set(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
21 let key = key.into();
22 self.fields.retain(|(k, _)| k != &key);
23 self.fields.push((key, value.into()));
24 self
25 }
26
27 pub fn id_site(self, id_site: impl Into<IdSite>) -> Self {
28 self.set("idSite", id_site.into().to_param())
29 }
30
31 pub fn period(self, period: Period) -> Self {
32 let (p, date) = period.to_params();
33 self.set("period", p).set("date", date)
34 }
35
36 pub fn segment(self, segment: impl Into<Segment>) -> Self {
37 self.set("segment", segment.into().as_str().to_string())
38 }
39
40 pub fn limit(self, limit: Limit) -> Self {
41 self.set("filter_limit", limit.to_param())
42 }
43
44 pub fn offset(self, offset: u32) -> Self {
45 self.set("filter_offset", offset.to_string())
46 }
47
48 pub fn fields(&self) -> &[(String, String)] {
50 &self.fields
51 }
52
53 pub fn to_bulk_query(&self, method: &str) -> String {
56 let mut pairs: Vec<(&str, &str)> = vec![("method", method)];
57 for (k, v) in &self.fields {
58 pairs.push((k.as_str(), v.as_str()));
59 }
60 let encoded: Vec<String> = pairs
61 .iter()
62 .map(|(k, v)| format!("{}={}", urlencode(k), urlencode(v)))
63 .collect();
64 encoded.join("&")
65 }
66}
67
68fn urlencode(s: &str) -> String {
69 url::form_urlencoded::byte_serialize(s.as_bytes()).collect()
70}