gen_api_wrapper/
params.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6//
7// Originally from https://gitlab.kitware.com/utils/rust-gitlab
8//
9// Modified in an attempt to make it general beyond just gitlab
10//
11
12//! Endpoint prelude
13
14use std::borrow::Cow;
15
16use url::Url;
17
18/// A trait representing a parameter value.
19pub trait ParamValue<'a> {
20    #[allow(clippy::wrong_self_convention)]
21    /// The parameter value as a string.
22    fn as_value(&self) -> Cow<'a, str>;
23}
24
25impl ParamValue<'static> for bool {
26    fn as_value(&self) -> Cow<'static, str> {
27        if *self {
28            "true".into()
29        } else {
30            "false".into()
31        }
32    }
33}
34
35impl<'a> ParamValue<'a> for &'a str {
36    fn as_value(&self) -> Cow<'a, str> {
37        (*self).into()
38    }
39}
40
41impl ParamValue<'static> for String {
42    fn as_value(&self) -> Cow<'static, str> {
43        self.clone().into()
44    }
45}
46
47impl<'a> ParamValue<'a> for &'a String {
48    fn as_value(&self) -> Cow<'a, str> {
49        (*self).into()
50    }
51}
52
53impl<'a> ParamValue<'a> for Cow<'a, str> {
54    fn as_value(&self) -> Cow<'a, str> {
55        self.clone()
56    }
57}
58
59impl<'a, 'b: 'a> ParamValue<'a> for &'b Cow<'a, str> {
60    fn as_value(&self) -> Cow<'a, str> {
61        (*self).clone()
62    }
63}
64
65impl ParamValue<'static> for u64 {
66    fn as_value(&self) -> Cow<'static, str> {
67        format!("{}", self).into()
68    }
69}
70
71impl ParamValue<'static> for f64 {
72    fn as_value(&self) -> Cow<'static, str> {
73        format!("{}", self).into()
74    }
75}
76
77/// A structure for form parameters.
78#[derive(Debug, Default, PartialEq, Eq, Clone)]
79pub struct FormParams<'a> {
80    params: Vec<(Cow<'a, str>, Cow<'a, str>)>,
81}
82
83impl<'a> FormParams<'a> {
84    /// Push a single parameter.
85    pub fn push<'b, K, V>(&mut self, key: K, value: V) -> &mut Self
86    where
87        K: Into<Cow<'a, str>>,
88        V: ParamValue<'b>,
89        'b: 'a,
90    {
91        self.params.push((key.into(), value.as_value()));
92        self
93    }
94
95    /// Push a single parameter.
96    pub fn push_opt<'b, K, V>(&mut self, key: K, value: Option<V>) -> &mut Self
97    where
98        K: Into<Cow<'a, str>>,
99        V: ParamValue<'b>,
100        'b: 'a,
101    {
102        if let Some(value) = value {
103            self.params.push((key.into(), value.as_value()));
104        }
105        self
106    }
107
108    /// Push a set of parameters.
109    pub fn extend<'b, I, K, V>(&mut self, iter: I) -> &mut Self
110    where
111        I: Iterator<Item = (K, V)>,
112        K: Into<Cow<'a, str>>,
113        V: ParamValue<'b>,
114        'b: 'a,
115    {
116        self.params
117            .extend(iter.map(|(key, value)| (key.into(), value.as_value())));
118        self
119    }
120}
121
122/// A structure for query parameters.
123#[derive(Debug, Default, PartialEq, Eq, Clone)]
124pub struct QueryParams<'a> {
125    params: Vec<(Cow<'a, str>, Cow<'a, str>)>,
126}
127
128impl<'a> QueryParams<'a> {
129    /// Push a single parameter.
130    pub fn push<'b, K, V>(&mut self, key: K, value: V) -> &mut Self
131    where
132        K: Into<Cow<'a, str>>,
133        V: ParamValue<'b>,
134        'b: 'a,
135    {
136        self.params.push((key.into(), value.as_value()));
137        self
138    }
139
140    /// Push a single parameter.
141    pub fn push_opt<'b, K, V>(&mut self, key: K, value: Option<V>) -> &mut Self
142    where
143        K: Into<Cow<'a, str>>,
144        V: ParamValue<'b>,
145        'b: 'a,
146    {
147        if let Some(value) = value {
148            self.params.push((key.into(), value.as_value()));
149        }
150        self
151    }
152
153    /// Push a set of parameters.
154    pub fn extend<'b, I, K, V>(&mut self, iter: I) -> &mut Self
155    where
156        I: Iterator<Item = (K, V)>,
157        K: Into<Cow<'a, str>>,
158        V: ParamValue<'b>,
159        'b: 'a,
160    {
161        self.params
162            .extend(iter.map(|(key, value)| (key.into(), value.as_value())));
163        self
164    }
165
166    /// Add the parameters to a URL.
167    pub fn add_to_url(&self, url: &mut Url) {
168        let mut pairs = url.query_pairs_mut();
169        pairs.extend_pairs(self.params.iter());
170    }
171}
172
173#[cfg(test)]
174mod tests {
175    use super::*;
176
177    #[test]
178    fn bool_str() {
179        let items = &[(true, "true"), (false, "false")];
180
181        for (i, s) in items {
182            assert_eq!((*i).as_value(), *s);
183        }
184    }
185}