1use std::sync::Arc;
2
3use crate::{
4 auth::AuthConfig, BaseUrls, HttpTransport, MetadataClient, OnDemandClient, RealtimeClient,
5 ReqwestTransport, Result, RetryConfig, RetryTransport, SnapshotClient, TokenManager,
6};
7
8#[derive(Debug, Clone)]
10pub struct ClientConfig {
11 pub base_urls: BaseUrls,
13 pub auth: Option<AuthConfig>,
15 pub retry: RetryConfig,
17 pub timeout: std::time::Duration,
19 pub enable_retry: bool,
21}
22
23impl Default for ClientConfig {
24 fn default() -> Self {
25 Self {
26 base_urls: BaseUrls::default(),
27 auth: None,
28 retry: RetryConfig::default(),
29 timeout: std::time::Duration::from_secs(60),
30 enable_retry: true,
31 }
32 }
33}
34
35pub struct WmeClient {
37 transport: Arc<dyn HttpTransport>,
38 token_manager: Option<TokenManager>,
39 base_urls: BaseUrls,
40}
41
42impl WmeClient {
43 pub async fn new(config: ClientConfig) -> Result<Self> {
45 let base_transport = Arc::new(ReqwestTransport::new()?);
46
47 let transport: Arc<dyn HttpTransport> = if config.enable_retry {
49 Arc::new(RetryTransport::new(base_transport, config.retry))
50 } else {
51 base_transport
52 };
53
54 let token_manager = config
55 .auth
56 .map(|auth| TokenManager::new(transport.clone(), auth));
57
58 Ok(Self {
59 transport,
60 token_manager,
61 base_urls: config.base_urls,
62 })
63 }
64
65 pub fn builder() -> WmeClientBuilder {
67 WmeClientBuilder::new()
68 }
69
70 pub fn metadata(&self) -> MetadataClient<'_> {
72 MetadataClient::new(self)
73 }
74
75 pub fn snapshot(&self) -> SnapshotClient<'_> {
77 SnapshotClient::new(self)
78 }
79
80 pub fn on_demand(&self) -> OnDemandClient<'_> {
82 OnDemandClient::new(self)
83 }
84
85 pub fn realtime(&self) -> RealtimeClient<'_> {
87 RealtimeClient::new(self)
88 }
89
90 pub(crate) fn transport(&self) -> &Arc<dyn HttpTransport> {
92 &self.transport
93 }
94
95 pub(crate) fn base_urls(&self) -> &BaseUrls {
97 &self.base_urls
98 }
99
100 pub(crate) async fn auth_headers(
102 &self,
103 ) -> Result<Option<std::collections::HashMap<String, String>>> {
104 if let Some(token_manager) = &self.token_manager {
105 let token = token_manager.get_access_token().await?;
106 let mut headers = std::collections::HashMap::new();
107 headers.insert("Authorization".to_string(), format!("Bearer {}", token));
108 Ok(Some(headers))
109 } else {
110 Ok(None)
111 }
112 }
113
114 pub fn token_manager(&self) -> Option<&TokenManager> {
122 self.token_manager.as_ref()
123 }
124}
125
126pub struct WmeClientBuilder {
128 config: ClientConfig,
129}
130
131impl WmeClientBuilder {
132 pub fn new() -> Self {
134 Self {
135 config: ClientConfig::default(),
136 }
137 }
138
139 pub fn api_url(mut self, url: impl Into<String>) -> Self {
141 self.config.base_urls.api = url.into();
142 self
143 }
144
145 pub fn auth_url(mut self, url: impl Into<String>) -> Self {
147 self.config.base_urls.auth = url.into();
148 self
149 }
150
151 pub fn realtime_url(mut self, url: impl Into<String>) -> Self {
153 self.config.base_urls.realtime = url.into();
154 self
155 }
156
157 pub fn credentials(mut self, username: impl Into<String>, password: impl Into<String>) -> Self {
159 self.config.auth = Some(AuthConfig {
160 username: username.into(),
161 password: password.into(),
162 auth_url: self.config.base_urls.auth.clone(),
163 });
164 self
165 }
166
167 pub fn retry(mut self, retry: RetryConfig) -> Self {
169 self.config.retry = retry;
170 self
171 }
172
173 pub fn disable_retry(mut self) -> Self {
175 self.config.enable_retry = false;
176 self
177 }
178
179 pub fn timeout(mut self, timeout: std::time::Duration) -> Self {
181 self.config.timeout = timeout;
182 self
183 }
184
185 pub async fn build(self) -> Result<WmeClient> {
187 WmeClient::new(self.config).await
188 }
189}
190
191impl Default for WmeClientBuilder {
192 fn default() -> Self {
193 Self::new()
194 }
195}