1pub mod alert;
2pub mod change;
3
4use headers::authorization::{Authorization, Bearer};
5use headers::{ContentType, HeaderMapExt};
6use hyper::client::connect::HttpConnector;
7use hyper::{Body, Method, StatusCode};
8use hyper_tls::HttpsConnector;
9use std::error::Error;
10use std::fmt::{self, Display, Formatter};
11
12pub const GET: Method = Method::GET;
13pub const POST: Method = Method::POST;
14pub const PUT: Method = Method::PUT;
15
16#[derive(Debug)]
17pub enum ApiType {
18 Alert,
19 Change,
20}
21
22#[derive(Debug)]
23pub enum BigPandaError {
24 NetworkError(hyper::Error),
25 HTTPError(StatusCode),
26}
27
28impl Display for BigPandaError {
29 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
30 match *self {
31 BigPandaError::NetworkError(ref err) => err.fmt(formatter),
32 BigPandaError::HTTPError(ref status_code) => {
33 write!(formatter, "Invalid status code: {}", status_code)
34 }
35 }
36 }
37}
38
39impl Error for BigPandaError {
40 fn source(&self) -> Option<&(dyn Error + 'static)> {
41 match *self {
42 BigPandaError::NetworkError(ref err) => Some(err),
43 _ => None,
44 }
45 }
46}
47
48pub struct Client {
49 api_type: ApiType,
50 app_key: String,
51 auth_token: String,
52 auth_header: Authorization<Bearer>,
53 http_client: hyper::Client<HttpsConnector<HttpConnector>>,
54}
55
56impl Client {
57 pub fn new(
58 api_type: ApiType,
59 app_key: &str,
60 auth_token: &str
61 ) -> Client {
62 Client {
63 api_type: api_type,
64 app_key: app_key.to_string(),
65 auth_token: auth_token.to_string(),
66 auth_header: Authorization::bearer(auth_token).unwrap(),
67 http_client: hyper::Client::builder().build(HttpsConnector::new()),
68 }
69 }
70
71 async fn send_request(
72 &self,
73 method: Method,
74 url: &str,
75 body: Body,
76 ) -> Result<(), BigPandaError> {
77 let mut request = hyper::Request::builder()
78 .method(method)
79 .uri(&*url)
80 .body(body)
81 .unwrap();
82
83 request.headers_mut().typed_insert(ContentType::json());
84 request.headers_mut().typed_insert(self.auth_header.clone());
85
86 if matches!(self.api_type, ApiType::Change) {
88 request.headers_mut()
89 .append("x-bp-app-key", self.app_key.parse().unwrap());
90 }
91
92 let response = self
93 .http_client
94 .request(request)
95 .await
96 .map_err(BigPandaError::NetworkError)?;
97
98 match response.status() {
99 StatusCode::CREATED | StatusCode::OK | StatusCode::NO_CONTENT => {}
100 error => return Err(BigPandaError::HTTPError(error)),
101 };
102
103 Ok(())
104 }
105}