use std::collections::HashMap;
use log::error;
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
use crate::api::models::api_error::SquareApiError;
use crate::config;
use crate::http::client::config::SquareHttpClientConfig;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Headers {
pub headers: HashMap<String, String>,
}
impl Headers {
pub fn has_user_agent(&self) -> bool {
self.headers.contains_key("user-agent")
}
pub fn set_user_agent(&mut self, user_agent: &str) -> Option<String> {
self.insert("user-agent", user_agent)
}
pub fn insert(&mut self, header_name: &str, header_value: &str) -> Option<String> {
self.headers
.insert(String::from(header_name), String::from(header_value))
}
}
impl Default for Headers {
fn default() -> Self {
let mut headers = HashMap::new();
headers.insert(String::from("Content-Type"), String::from("application/json"));
headers.insert(String::from("Square-Version"), config::DEFAULT_API_VERSION.to_string());
headers.insert(String::from("accept"), String::from("application/json"));
headers.insert(String::from("user-agent"), SquareHttpClientConfig::default_user_agent());
headers.insert(String::from("Authorization"), config::get_default_authorization_token());
Self { headers }
}
}
impl TryFrom<&Headers> for HeaderMap {
type Error = SquareApiError;
fn try_from(headers: &Headers) -> Result<Self, Self::Error> {
let mut header_map = Self::new();
for (k, v) in &headers.headers {
let header_name = HeaderName::from_bytes(k.as_bytes()).map_err(|e| {
let msg = format!("Error generating {} header name: {}", k, e);
error!("{}", msg);
SquareApiError::new(&msg)
})?;
let header_value = HeaderValue::from_bytes(v.as_bytes()).map_err(|e| {
let msg = format!("Error generating {} header value for header {}: {}", v, k, e);
error!("{}", msg);
SquareApiError::new(&msg)
})?;
header_map.insert(header_name, header_value);
}
Ok(header_map)
}
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use reqwest::header::HeaderMap;
use crate::config;
use crate::http::client::config::SquareHttpClientConfig;
use crate::http::headers::Headers;
#[test]
fn headers_default() {
let headers = Headers::default();
assert_eq!(
headers.headers.get("Content-Type"),
Some(&String::from("application/json"))
);
assert_eq!(headers.headers.get("Square-Version"), Some(&String::from("2023-09-25")));
assert_eq!(headers.headers.get("accept"), Some(&String::from("application/json")));
assert_eq!(
headers.headers.get("user-agent"),
Some(&SquareHttpClientConfig::default_user_agent())
);
assert_eq!(
headers.headers.get("Authorization"),
Some(&config::get_default_authorization_token())
);
assert!(headers.has_user_agent());
}
#[test]
fn headers_has_user_agent() {
let mut headers = Headers::default();
headers.headers = HashMap::new();
assert!(!headers.has_user_agent());
headers.set_user_agent("some-user-agent");
assert!(headers.has_user_agent());
}
#[test]
fn headers_set_user_agent() {
let mut headers = Headers::default();
assert!(!(headers.headers.get("user-agent") == Some(&String::from("some-user-agent"))));
headers.set_user_agent("some-user-agent");
assert_eq!(
Some(&String::from("some-user-agent")),
headers.headers.get("user-agent")
);
}
#[test]
fn try_from_ok() {
assert!(HeaderMap::try_from(&Headers::default()).is_ok());
}
#[test]
fn try_from_error() {
let mut headers = Headers::default();
headers.headers = HashMap::new();
headers
.headers
.insert(String::from("some_faulty_code\u{1234}"), String::from("some_value"));
assert!(HeaderMap::try_from(&headers).is_err());
}
}