use crate::one_api::{balance, message_status, send_messages};
use crate::one_api::{error::Error, result::Result};
use reqwest::{
blocking::Client as HTTPClient, header::HeaderMap, header::HeaderValue, header::ACCEPT,
header::AUTHORIZATION, header::CONTENT_TYPE,
};
use std::default::Default;
pub const HOSTNAME: &str = "https://platform.clickatell.com";
const MESSAGE_PATH: &str = "/v1/message";
const BALANCE_PATH: &str = "/v1/balance";
const APPLICATION_JSON: &str = "application/json";
pub struct BlockingClient {
hostname: String,
http_client: HTTPClient,
}
impl BlockingClient {
pub fn new(api_key: &str) -> Result<Self> {
Self::builder().api_key(api_key).build()
}
pub fn builder() -> BlockingClientBuilder {
BlockingClientBuilder::default()
}
pub fn send_messages(
&self,
send_messages_request: send_messages::Request,
) -> Result<send_messages::Response> {
if send_messages_request.message_count() >= 100 {
return Err(Error::TooManyMessages);
}
let response = self
.http_client
.post(format!("{}{MESSAGE_PATH}", self.hostname))
.json(&send_messages_request)
.send()?;
Ok(response.json::<send_messages::Response>()?)
}
pub fn message_status(
&self,
request: message_status::Request,
) -> Result<message_status::Response> {
let response = self
.http_client
.get(format!("{}{MESSAGE_PATH}/{}", self.hostname, request))
.send()?;
Ok(response.json::<message_status::Response>()?)
}
pub fn balance(&self) -> Result<balance::Response> {
let response = self
.http_client
.get(format!("{}{BALANCE_PATH}", self.hostname))
.send()?;
Ok(response.json::<balance::Response>()?)
}
}
pub struct BlockingClientBuilder {
hostname: Option<String>,
api_key: Option<String>,
}
impl Default for BlockingClientBuilder {
fn default() -> Self {
BlockingClientBuilder {
hostname: Some(HOSTNAME.to_string()),
api_key: None,
}
}
}
impl BlockingClientBuilder {
pub fn api_key(mut self, api_key: &str) -> Self {
self.api_key = Some(api_key.to_string());
self
}
pub fn hostname(mut self, hostname: &str) -> Self {
self.hostname = Some(hostname.to_string());
self
}
pub fn build(self) -> Result<BlockingClient> {
match (self.api_key, self.hostname) {
(Some(api_key), Some(hostname)) => {
let mut headers = HeaderMap::new();
let mut auth_value = HeaderValue::from_str(&api_key)?;
auth_value.set_sensitive(true);
headers.insert(AUTHORIZATION, auth_value);
headers.insert(CONTENT_TYPE, HeaderValue::from_str(APPLICATION_JSON)?);
headers.insert(ACCEPT, HeaderValue::from_str(APPLICATION_JSON)?);
let http_client = HTTPClient::builder().default_headers(headers).build()?;
Ok(BlockingClient {
hostname,
http_client,
})
}
(None, _) => Err(Error::ApiKeyNotSet),
(Some(_), None) => Err(Error::HostnameNotSet),
}
}
}