clickatell_api/one_api/
blocking_client.rs1use crate::one_api::{balance, message_status, send_messages};
2use crate::one_api::{error::Error, result::Result};
3use reqwest::{
4 blocking::Client as HTTPClient, header::HeaderMap, header::HeaderValue, header::ACCEPT,
5 header::AUTHORIZATION, header::CONTENT_TYPE,
6};
7use std::default::Default;
8
9pub const HOSTNAME: &str = "https://platform.clickatell.com";
10const MESSAGE_PATH: &str = "/v1/message";
11const BALANCE_PATH: &str = "/v1/balance";
12const APPLICATION_JSON: &str = "application/json";
13
14pub struct BlockingClient {
16 hostname: String,
17 http_client: HTTPClient,
18}
19
20impl BlockingClient {
21 pub fn new(api_key: &str) -> Result<Self> {
22 Self::builder().api_key(api_key).build()
23 }
24
25 pub fn builder() -> BlockingClientBuilder {
26 BlockingClientBuilder::default()
27 }
28
29 pub fn send_messages(
46 &self,
47 send_messages_request: send_messages::Request,
48 ) -> Result<send_messages::Response> {
49 if send_messages_request.message_count() >= 100 {
50 return Err(Error::TooManyMessages);
51 }
52
53 let response = self
54 .http_client
55 .post(format!("{}{MESSAGE_PATH}", self.hostname))
56 .json(&send_messages_request)
57 .send()?;
58
59 Ok(response.json::<send_messages::Response>()?)
60 }
61
62 pub fn message_status(
70 &self,
71 request: message_status::Request,
72 ) -> Result<message_status::Response> {
73 let response = self
74 .http_client
75 .get(format!("{}{MESSAGE_PATH}/{}", self.hostname, request))
76 .send()?;
77
78 Ok(response.json::<message_status::Response>()?)
79 }
80
81 pub fn balance(&self) -> Result<balance::Response> {
88 let response = self
89 .http_client
90 .get(format!("{}{BALANCE_PATH}", self.hostname))
91 .send()?;
92
93 Ok(response.json::<balance::Response>()?)
94 }
95}
96
97pub struct BlockingClientBuilder {
100 hostname: Option<String>,
101 api_key: Option<String>,
102}
103
104impl Default for BlockingClientBuilder {
105 fn default() -> Self {
106 BlockingClientBuilder {
107 hostname: Some(HOSTNAME.to_string()),
108 api_key: None,
109 }
110 }
111}
112
113impl BlockingClientBuilder {
114 pub fn api_key(mut self, api_key: &str) -> Self {
115 self.api_key = Some(api_key.to_string());
116 self
117 }
118
119 pub fn hostname(mut self, hostname: &str) -> Self {
120 self.hostname = Some(hostname.to_string());
121 self
122 }
123
124 pub fn build(self) -> Result<BlockingClient> {
125 match (self.api_key, self.hostname) {
126 (Some(api_key), Some(hostname)) => {
127 let mut headers = HeaderMap::new();
128
129 let mut auth_value = HeaderValue::from_str(&api_key)?;
130 auth_value.set_sensitive(true);
131
132 headers.insert(AUTHORIZATION, auth_value);
133 headers.insert(CONTENT_TYPE, HeaderValue::from_str(APPLICATION_JSON)?);
134 headers.insert(ACCEPT, HeaderValue::from_str(APPLICATION_JSON)?);
135
136 let http_client = HTTPClient::builder().default_headers(headers).build()?;
137
138 Ok(BlockingClient {
139 hostname,
140 http_client,
141 })
142 }
143 (None, _) => Err(Error::ApiKeyNotSet),
144 (Some(_), None) => Err(Error::HostnameNotSet),
145 }
146 }
147}