1use url::form_urlencoded;
2use url::Url;
3
4use std::time::Duration;
5
6use crate::error::Error;
7use crate::requests::{Request, Response};
8
9pub const API_URL: &'static str = "https://api.pushover.net";
10pub const API_VERSION: &'static str = "1";
11const DEFAULT_TIMEOUT: u64 = 30;
12
13pub struct API {
14 base_url: String,
15 timeout: Duration,
16}
17
18impl API {
19 pub fn new() -> Self {
20 Self {
21 timeout: Duration::from_secs(DEFAULT_TIMEOUT),
22 base_url: API_URL.to_owned(),
23 }
24 }
25
26 pub fn timeout(mut self, timeout: Duration) -> Self {
27 self.timeout = timeout;
28 self
29 }
30
31 pub fn base_url(mut self, url: &str) -> Self {
32 self.base_url = url.to_owned();
33 self
34 }
35
36 pub fn send<R: Request>(&self, request: &R) -> Result<<R as Request>::ResponseType, Error> {
37 let mut url = Url::parse(&self.base_url).unwrap();
38 url.set_path(API_VERSION);
39
40 let client_builder = reqwest::blocking::ClientBuilder::new().timeout(self.timeout);
41
42 request.build_url(&mut url);
43
44 let req = client_builder.build()?.request(request.get_method(), url);
45
46 let req = if let Some(params) = request.get_form_parameters() {
47 let encoded: String = form_urlencoded::Serializer::new(String::new())
48 .extend_pairs(params.into_iter())
49 .finish();
50
51 req.body(encoded)
52 } else {
53 req
54 };
55
56 let res = req.send()?;
57
58 res.json()
59 .map_err(From::from)
60 .and_then(|value| match value {
61 Response::Success::<R>(raw) => Ok(R::map(raw)),
62 Response::Error::<R>(err) => Err(err.into()),
63 })
64 }
65
66 pub async fn send_async<R: Request>(
67 &self,
68 request: &R,
69 ) -> Result<<R as Request>::ResponseType, Error> {
70 let mut url = Url::parse(&self.base_url).unwrap();
71 url.set_path(API_VERSION);
72
73 let client_builder = reqwest::ClientBuilder::new().timeout(self.timeout);
74
75 request.build_url(&mut url);
76
77 let req = client_builder.build()?.request(request.get_method(), url);
78
79 let req = if let Some(params) = request.get_form_parameters() {
80 let encoded: String = form_urlencoded::Serializer::new(String::new())
81 .extend_pairs(params.into_iter())
82 .finish();
83
84 req.body(encoded)
85 } else {
86 req
87 };
88
89 let res = req.send().await?;
90
91 res.json()
92 .await
93 .map_err(From::from)
94 .and_then(|value| match value {
95 Response::Success::<R>(raw) => Ok(R::map(raw)),
96 Response::Error::<R>(err) => Err(err.into()),
97 })
98 }
99}