square_api_client/http/
headers.rs

1//! Represents a collection of Request Headers
2
3use super::client::HttpClientConfiguration;
4use crate::config;
5use crate::models::errors::ApiError;
6use log::error;
7use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
8use std::collections::HashMap;
9
10/// A collection of Request Headers
11#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct Headers {
13    /// The request headers as key-value pairs
14    pub headers: HashMap<String, String>,
15}
16
17impl Headers {
18    /// Indicates whether the headers include the User Agent header
19    pub fn has_user_agent(&self) -> bool {
20        self.headers.contains_key("user-agent")
21    }
22
23    /// Sets the User Agent header
24    pub fn set_user_agent(&mut self, user_agent: &str) -> Option<String> {
25        self.insert("user-agent", user_agent)
26    }
27
28    /// Adds a request header to the collection
29    pub fn insert(&mut self, header_name: &str, header_value: &str) -> Option<String> {
30        self.headers.insert(String::from(header_name), String::from(header_value))
31    }
32}
33
34impl Default for Headers {
35    /// The default set of request headers
36    /// * Content-Type: application/json
37    /// * Square-Version
38    /// * accept: application/json
39    /// * user-agent
40    /// * Authorization
41    fn default() -> Self {
42        let mut headers = HashMap::new();
43
44        headers.insert(String::from("Content-Type"), String::from("application/json"));
45        headers
46            .insert(String::from("Square-Version"), String::from(config::DEFAULT_SQUARE_VERSION));
47        headers.insert(String::from("accept"), String::from("application/json"));
48        headers.insert(String::from("user-agent"), HttpClientConfiguration::default_user_agent());
49        headers.insert(String::from("Authorization"), config::default_authorization());
50
51        Self { headers }
52    }
53}
54
55impl TryFrom<&Headers> for HeaderMap {
56    type Error = ApiError;
57
58    /// Converts `Headers` into Reqwest lib's `HeaderMap`
59    fn try_from(headers: &Headers) -> Result<Self, Self::Error> {
60        let mut header_map = Self::new();
61        for (k, v) in &headers.headers {
62            let header_name = HeaderName::from_bytes(k.as_bytes()).map_err(|e| {
63                let msg = format!("Error generating {} header name: {}", k, e);
64                error!("{}", msg);
65                ApiError::new(&msg)
66            })?;
67            let header_value = HeaderValue::from_bytes(v.as_bytes()).map_err(|e| {
68                let msg = format!("Error generating {} header value for header {}: {}", v, k, e);
69                error!("{}", msg);
70                ApiError::new(&msg)
71            })?;
72            header_map.insert(header_name, header_value);
73        }
74
75        Ok(header_map)
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use crate::config;
82    use crate::http::client::HttpClientConfiguration;
83    use crate::http::Headers;
84    use reqwest::header::HeaderMap;
85    use std::collections::HashMap;
86
87    #[test]
88    fn headers_default() {
89        let headers = Headers::default();
90        assert_eq!(headers.headers.get("Content-Type"), Some(&String::from("application/json")));
91        assert_eq!(headers.headers.get("Square-Version"), Some(&String::from("2022-02-16")));
92        assert_eq!(headers.headers.get("accept"), Some(&String::from("application/json")));
93        assert_eq!(
94            headers.headers.get("user-agent"),
95            Some(&HttpClientConfiguration::default_user_agent())
96        );
97        assert_eq!(headers.headers.get("Authorization"), Some(&config::default_authorization()));
98        assert!(headers.has_user_agent());
99    }
100
101    #[test]
102    fn headers_has_user_agent() {
103        let mut headers = Headers::default();
104        headers.headers = HashMap::new();
105        assert!(!headers.has_user_agent());
106        headers.set_user_agent("some-user-agent");
107        assert!(headers.has_user_agent());
108    }
109
110    #[test]
111    fn headers_set_user_agent() {
112        let mut headers = Headers::default();
113        assert!(!(headers.headers.get("user-agent") == Some(&String::from("some-user-agent"))));
114        headers.set_user_agent("some-user-agent");
115        assert_eq!(Some(&String::from("some-user-agent")), headers.headers.get("user-agent"));
116    }
117
118    #[test]
119    fn try_from_ok() {
120        assert!(HeaderMap::try_from(&Headers::default()).is_ok());
121    }
122
123    #[test]
124    fn try_from_error() {
125        let mut headers = Headers::default();
126        headers.headers = HashMap::new();
127        headers
128            .headers
129            .insert(String::from("some_faulty_code\u{1234}"), String::from("some_value"));
130        assert!(HeaderMap::try_from(&headers).is_err());
131    }
132}