1use std::time::Duration;
4
5use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, USER_AGENT};
6
7use crate::VERSION;
8
9pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
11
12#[derive(Debug, Clone)]
18pub struct Client {
19 pub(crate) api_key: String,
20 pub(crate) base_url: String,
21 pub(crate) http: reqwest::Client,
22}
23
24impl Client {
25 pub fn new(api_key: impl Into<String>) -> Self {
29 ClientBuilder::new(api_key)
30 .build()
31 .expect("default reqwest::Client should always build")
32 }
33
34 pub fn builder(api_key: impl Into<String>) -> ClientBuilder {
36 ClientBuilder::new(api_key)
37 }
38
39 pub fn api_key(&self) -> &str {
41 &self.api_key
42 }
43
44 pub fn base_url(&self) -> &str {
46 &self.base_url
47 }
48}
49
50#[derive(Debug)]
52pub struct ClientBuilder {
53 api_key: String,
54 base_url: String,
55 timeout: Duration,
56 http: Option<reqwest::Client>,
57}
58
59impl ClientBuilder {
60 pub fn new(api_key: impl Into<String>) -> Self {
62 Self {
63 api_key: api_key.into(),
64 base_url: crate::DEFAULT_BASE_URL.to_string(),
65 timeout: DEFAULT_TIMEOUT,
66 http: None,
67 }
68 }
69
70 pub fn base_url(mut self, url: impl Into<String>) -> Self {
72 self.base_url = url.into();
73 self
74 }
75
76 pub fn timeout(mut self, timeout: Duration) -> Self {
79 self.timeout = timeout;
80 self
81 }
82
83 pub fn http_client(mut self, http: reqwest::Client) -> Self {
86 self.http = Some(http);
87 self
88 }
89
90 pub fn build(self) -> Result<Client, reqwest::Error> {
92 let http = match self.http {
93 Some(h) => h,
94 None => {
95 let mut headers = HeaderMap::new();
96 headers.insert(ACCEPT, HeaderValue::from_static("application/json"));
97 headers.insert(
98 USER_AGENT,
99 HeaderValue::from_str(&format!("unirate-rust/{VERSION}"))
100 .expect("user agent must be ASCII"),
101 );
102 reqwest::Client::builder()
103 .timeout(self.timeout)
104 .default_headers(headers)
105 .build()?
106 }
107 };
108
109 let base_url = self.base_url.trim_end_matches('/').to_string();
111
112 Ok(Client {
113 api_key: self.api_key,
114 base_url,
115 http,
116 })
117 }
118}