square_api_client/http/
headers.rs1use 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#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct Headers {
13 pub headers: HashMap<String, String>,
15}
16
17impl Headers {
18 pub fn has_user_agent(&self) -> bool {
20 self.headers.contains_key("user-agent")
21 }
22
23 pub fn set_user_agent(&mut self, user_agent: &str) -> Option<String> {
25 self.insert("user-agent", user_agent)
26 }
27
28 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 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 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}