1pub mod api_client;
2pub mod at_home;
3pub mod auth;
4pub mod author;
5pub mod captcha;
6pub mod chapter;
7pub mod cover;
8pub mod custom_list;
9pub mod feed;
10pub mod forums;
11pub mod legacy;
12pub mod manga;
13cfg_oauth! {
14 pub mod oauth;
15}
16pub mod ping;
17pub mod rating;
18pub mod report;
19pub mod scanlation_group;
20pub mod search;
21pub mod settings;
22pub mod statistics;
23pub mod upload;
24pub mod user;
25
26use crate::Result;
27pub use mangadex_api_schema::v5 as schema;
28use mangadex_api_schema::v5::oauth::ClientInfo;
29pub(crate) use mangadex_api_schema::v5::AuthTokens;
30
31use reqwest::Client;
32
33use std::sync::Arc;
34use tokio::sync::RwLock;
35
36#[cfg(feature = "utils")]
37use crate::utils::download::DownloadBuilder;
38use crate::v5::api_client::ApiClientEndpoint;
39use crate::v5::at_home::AtHomeBuilder;
40use crate::v5::auth::AuthBuilder;
41use crate::v5::author::AuthorBuilder;
42use crate::v5::captcha::CaptchaBuilder;
43use crate::v5::chapter::ChapterBuilder;
44use crate::v5::cover::CoverBuilder;
45use crate::v5::custom_list::CustomListBuilder;
46use crate::v5::feed::FeedBuilder;
47use crate::v5::forums::ForumsEndpoint;
48use crate::v5::legacy::LegacyBuilder;
49use crate::v5::manga::MangaBuilder;
50#[cfg(feature = "oauth")]
51use crate::v5::oauth::OAuthBuider;
52use crate::v5::ping::PingEndpointBuilder;
53use crate::v5::rating::RatingBuilder;
54use crate::v5::report::ReportBuilder;
55use crate::v5::scanlation_group::ScanlationGroupBuilder;
56use crate::v5::search::SearchBuilder;
57use crate::v5::settings::SettingsBuilder;
58use crate::v5::statistics::StatisticsBuilder;
59use crate::v5::upload::UploadBuilder;
60use crate::v5::user::UserBuilder;
61use crate::HttpClient;
62use crate::HttpClientRef;
63
64#[derive(Clone, Debug)]
66#[non_exhaustive]
67pub struct MangaDexClient {
68 pub http_client: HttpClientRef,
69}
70
71impl Default for MangaDexClient {
72 fn default() -> Self {
87 Self::new_with_http_client(HttpClient::default())
88 }
89}
90
91impl MangaDexClient {
92 pub fn new(client: Client) -> Self {
111 Self::new_with_http_client_ref(create_ref_counted_http_client(HttpClient::new(client)))
112 }
113
114 pub fn new_with_http_client_ref(http_client: HttpClientRef) -> Self {
116 Self { http_client }
117 }
118 pub fn new_with_http_client(http_client: HttpClient) -> Self {
148 Self::new_with_http_client_ref(create_ref_counted_http_client(http_client))
149 }
150
151 pub fn get_http_client(&self) -> HttpClientRef {
157 self.http_client.clone()
158 }
159
160 pub async fn set_auth_tokens(&self, auth_tokens: &AuthTokens) -> Result<()> {
161 let mut client = self.http_client.write().await;
162
163 client.set_auth_tokens(auth_tokens);
164 Ok(())
165 }
166
167 pub async fn clear_auth_tokens(&self) -> Result<()> {
168 let mut client = self.http_client.write().await;
169
170 client.clear_auth_tokens();
171 Ok(())
172 }
173 pub async fn get_auth_tokens(&self) -> Result<AuthTokens> {
174 let client = &self.http_client.read().await;
175 client
176 .get_tokens()
177 .cloned()
178 .ok_or(crate::error::Error::MissingTokens)
179 }
180
181 pub async fn set_captcha<A: Into<String>>(&self, captcha: A) -> Result<()> {
182 let mut client = self.http_client.write().await;
183 client.set_captcha(captcha);
184 Ok(())
185 }
186 pub async fn get_captcha(&self) -> Result<String> {
187 let client = &self.http_client.read().await;
188 client
189 .get_captcha()
190 .cloned()
191 .ok_or(crate::error::Error::MissingCaptcha)
192 }
193 pub async fn clear_captcha(&self) -> Result<()> {
194 let mut client = self.http_client.write().await;
195 client.clear_captcha();
196 Ok(())
197 }
198
199 cfg_oauth! {
200 pub async fn get_client_info(&self) -> Result<ClientInfo> {
201 let client = &self.http_client.read().await;
202 client
203 .get_client_info()
204 .cloned()
205 .ok_or(crate::error::Error::MissingClientInfo)
206 }
207 }
208 pub fn at_home(&self) -> AtHomeBuilder {
212 AtHomeBuilder::new(self.http_client.clone())
213 }
214
215 pub fn auth(&self) -> AuthBuilder {
221 AuthBuilder::new(self.http_client.clone())
222 }
223
224 pub fn author(&self) -> AuthorBuilder {
228 AuthorBuilder::new(self.http_client.clone())
229 }
230
231 pub fn captcha(&self) -> CaptchaBuilder {
235 CaptchaBuilder::new(self.http_client.clone())
236 }
237
238 pub fn chapter(&self) -> ChapterBuilder {
242 ChapterBuilder::new(self.http_client.clone())
243 }
244
245 pub fn client(&self) -> ApiClientEndpoint {
246 ApiClientEndpoint::new(self.http_client.clone())
247 }
248
249 pub fn cover(&self) -> CoverBuilder {
253 CoverBuilder::new(self.http_client.clone())
254 }
255
256 pub fn custom_list(&self) -> CustomListBuilder {
260 CustomListBuilder::new(self.http_client.clone())
261 }
262
263 pub fn feed(&self) -> FeedBuilder {
267 FeedBuilder::new(self.http_client.clone())
268 }
269
270 pub fn ping(&self) -> PingEndpointBuilder {
274 PingEndpointBuilder::new(self.http_client.clone())
275 }
276
277 pub fn legacy(&self) -> LegacyBuilder {
281 LegacyBuilder::new(self.http_client.clone())
282 }
283
284 pub fn manga(&self) -> MangaBuilder {
288 MangaBuilder::new(self.http_client.clone())
289 }
290
291 pub fn rating(&self) -> RatingBuilder {
295 RatingBuilder::new(self.http_client.clone())
296 }
297
298 pub fn report(&self) -> ReportBuilder {
302 ReportBuilder::new(self.http_client.clone())
303 }
304
305 pub fn scanlation_group(&self) -> ScanlationGroupBuilder {
309 ScanlationGroupBuilder::new(self.http_client.clone())
310 }
311
312 pub fn search(&self) -> SearchBuilder {
316 SearchBuilder::new(self.http_client.clone())
317 }
318
319 pub fn settings(&self) -> SettingsBuilder {
324 SettingsBuilder::new(self.http_client.clone())
325 }
326
327 pub fn statistics(&self) -> StatisticsBuilder {
331 StatisticsBuilder::new(self.http_client.clone())
332 }
333
334 pub fn upload(&self) -> UploadBuilder {
338 UploadBuilder::new(self.http_client.clone())
339 }
340
341 pub fn user(&self) -> UserBuilder {
345 UserBuilder::new(self.http_client.clone())
346 }
347
348 pub fn api_dev_client() -> Self {
351 Self::new_with_http_client(HttpClient::api_dev_client())
352 }
353 cfg_utils! {
354 pub fn download(&self) -> DownloadBuilder {
355 DownloadBuilder::new(self.http_client.clone())
356 }
357 }
358
359 pub fn forums(&self) -> ForumsEndpoint {
360 ForumsEndpoint::new(self.http_client.clone())
361 }
362
363 cfg_oauth! {
364 pub fn oauth(&self) -> OAuthBuider {
365 OAuthBuider::new(self.http_client.clone())
366 }
367 }
368 cfg_oauth! {
369 pub async fn set_client_info(&self, client_info: &ClientInfo) -> Result<()> {
370 let mut client = self.http_client.write().await;
371 client.set_client_info(client_info);
372 Ok(())
373 }
374 }
375 cfg_oauth! {
376 pub async fn clear_client_info(&self) -> Result<()> {
377 let mut client = self.http_client.write().await;
378 client.clear_client_info();
379 Ok(())
380 }
381 }
382 pub async fn get_reqwest_client(&self) -> reqwest::Client {
383 self.get_http_client().read().await.client.clone()
384 }
385}
386
387fn create_ref_counted_http_client(http_client: HttpClient) -> HttpClientRef {
389 Arc::new(RwLock::new(http_client))
390}