pushover/
client.rs

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}