Skip to main content

komga_sdk/apis/
books_api.rs

1/*
2 * Komga API
3 *
4 * Komga REST API.  ## Reference  Check the API reference: - on the [Komga website](https://komga.org/docs/openapi/komga-api) - on any running Komga instance at `/swagger-ui.html` - on [GitHub](https://raw.githubusercontent.com/gotson/komga/refs/heads/master/komga/docs/openapi.json)  ## Authentication  Most endpoints require authentication. Authentication is done using either: - Basic Authentication - Passing an API Key in the `X-API-Key` header  ## Sessions  Upon successful authentication, a session is created, and can be reused.  - By default, a `KOMGA-SESSION` cookie is set via `Set-Cookie` response header. This works well for browsers and clients that can handle cookies. - If you specify a header `X-Auth-Token` during authentication, the session ID will be returned via this same header. You can then pass that header again for subsequent requests to reuse the session.  If you need to set the session cookie later on, you can call `/api/v1/login/set-cookie` with `X-Auth-Token`. The response will contain the `Set-Cookie` header.  ## Remember Me  During authentication, if a request parameter `remember-me` is passed and set to `true`, the server will also return a `komga-remember-me` cookie. This cookie will be used to login automatically even if the session has expired.  ## Logout  You can explicitly logout an existing session by calling `/api/logout`. This would return a `204`.  ## Deprecation  API endpoints marked as deprecated will be removed in the next major version.
5 *
6 * The version of the OpenAPI document: 1.23.4
7 * 
8 * Generated by: https://openapi-generator.tech
9 */
10
11
12use reqwest;
13use serde::{Deserialize, Serialize, de::Error as _};
14use crate::{apis::ResponseContent, models};
15use super::{Error, configuration, ContentType};
16
17
18/// struct for typed errors of method [`book_analyze`]
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(untagged)]
21pub enum BookAnalyzeError {
22    Status400(models::ValidationErrorResponse),
23    UnknownValue(serde_json::Value),
24}
25
26/// struct for typed errors of method [`book_refresh_metadata`]
27#[derive(Debug, Clone, Serialize, Deserialize)]
28#[serde(untagged)]
29pub enum BookRefreshMetadataError {
30    Status400(models::ValidationErrorResponse),
31    UnknownValue(serde_json::Value),
32}
33
34/// struct for typed errors of method [`delete_book_file`]
35#[derive(Debug, Clone, Serialize, Deserialize)]
36#[serde(untagged)]
37pub enum DeleteBookFileError {
38    Status400(models::ValidationErrorResponse),
39    UnknownValue(serde_json::Value),
40}
41
42/// struct for typed errors of method [`delete_book_read_progress`]
43#[derive(Debug, Clone, Serialize, Deserialize)]
44#[serde(untagged)]
45pub enum DeleteBookReadProgressError {
46    Status400(models::ValidationErrorResponse),
47    UnknownValue(serde_json::Value),
48}
49
50/// struct for typed errors of method [`download_book_file`]
51#[derive(Debug, Clone, Serialize, Deserialize)]
52#[serde(untagged)]
53pub enum DownloadBookFileError {
54    Status400(models::ValidationErrorResponse),
55    UnknownValue(serde_json::Value),
56}
57
58/// struct for typed errors of method [`download_book_file1`]
59#[derive(Debug, Clone, Serialize, Deserialize)]
60#[serde(untagged)]
61pub enum DownloadBookFile1Error {
62    Status400(models::ValidationErrorResponse),
63    UnknownValue(serde_json::Value),
64}
65
66/// struct for typed errors of method [`get_all_books_deprecated`]
67#[derive(Debug, Clone, Serialize, Deserialize)]
68#[serde(untagged)]
69pub enum GetAllBooksDeprecatedError {
70    Status400(models::ValidationErrorResponse),
71    UnknownValue(serde_json::Value),
72}
73
74/// struct for typed errors of method [`get_book_by_id`]
75#[derive(Debug, Clone, Serialize, Deserialize)]
76#[serde(untagged)]
77pub enum GetBookByIdError {
78    Status400(models::ValidationErrorResponse),
79    UnknownValue(serde_json::Value),
80}
81
82/// struct for typed errors of method [`get_book_sibling_next`]
83#[derive(Debug, Clone, Serialize, Deserialize)]
84#[serde(untagged)]
85pub enum GetBookSiblingNextError {
86    Status400(models::ValidationErrorResponse),
87    UnknownValue(serde_json::Value),
88}
89
90/// struct for typed errors of method [`get_book_sibling_previous`]
91#[derive(Debug, Clone, Serialize, Deserialize)]
92#[serde(untagged)]
93pub enum GetBookSiblingPreviousError {
94    Status400(models::ValidationErrorResponse),
95    UnknownValue(serde_json::Value),
96}
97
98/// struct for typed errors of method [`get_books`]
99#[derive(Debug, Clone, Serialize, Deserialize)]
100#[serde(untagged)]
101pub enum GetBooksError {
102    Status400(models::ValidationErrorResponse),
103    UnknownValue(serde_json::Value),
104}
105
106/// struct for typed errors of method [`get_books_duplicates`]
107#[derive(Debug, Clone, Serialize, Deserialize)]
108#[serde(untagged)]
109pub enum GetBooksDuplicatesError {
110    Status400(models::ValidationErrorResponse),
111    UnknownValue(serde_json::Value),
112}
113
114/// struct for typed errors of method [`get_books_latest`]
115#[derive(Debug, Clone, Serialize, Deserialize)]
116#[serde(untagged)]
117pub enum GetBooksLatestError {
118    Status400(models::ValidationErrorResponse),
119    UnknownValue(serde_json::Value),
120}
121
122/// struct for typed errors of method [`get_books_on_deck`]
123#[derive(Debug, Clone, Serialize, Deserialize)]
124#[serde(untagged)]
125pub enum GetBooksOnDeckError {
126    Status400(models::ValidationErrorResponse),
127    UnknownValue(serde_json::Value),
128}
129
130/// struct for typed errors of method [`get_read_lists_by_book_id`]
131#[derive(Debug, Clone, Serialize, Deserialize)]
132#[serde(untagged)]
133pub enum GetReadListsByBookIdError {
134    Status400(models::ValidationErrorResponse),
135    UnknownValue(serde_json::Value),
136}
137
138/// struct for typed errors of method [`mark_book_read_progress`]
139#[derive(Debug, Clone, Serialize, Deserialize)]
140#[serde(untagged)]
141pub enum MarkBookReadProgressError {
142    Status400(models::ValidationErrorResponse),
143    UnknownValue(serde_json::Value),
144}
145
146/// struct for typed errors of method [`update_book_metadata`]
147#[derive(Debug, Clone, Serialize, Deserialize)]
148#[serde(untagged)]
149pub enum UpdateBookMetadataError {
150    Status400(models::ValidationErrorResponse),
151    UnknownValue(serde_json::Value),
152}
153
154/// struct for typed errors of method [`update_book_metadata_by_batch`]
155#[derive(Debug, Clone, Serialize, Deserialize)]
156#[serde(untagged)]
157pub enum UpdateBookMetadataByBatchError {
158    Status400(models::ValidationErrorResponse),
159    UnknownValue(serde_json::Value),
160}
161
162
163/// Required role: **ADMIN**
164pub async fn book_analyze(configuration: &configuration::Configuration, book_id: &str) -> Result<(), Error<BookAnalyzeError>> {
165    // add a prefix to parameters to efficiently prevent name collisions
166    let p_path_book_id = book_id;
167
168    let uri_str = format!("{}/api/v1/books/{bookId}/analyze", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
169    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
170
171    if let Some(ref user_agent) = configuration.user_agent {
172        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
173    }
174    if let Some(ref apikey) = configuration.api_key {
175        let key = apikey.key.clone();
176        let value = match apikey.prefix {
177            Some(ref prefix) => format!("{} {}", prefix, key),
178            None => key,
179        };
180        req_builder = req_builder.header("X-API-Key", value);
181    };
182    if let Some(ref auth_conf) = configuration.basic_auth {
183        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
184    };
185
186    let req = req_builder.build()?;
187    let resp = configuration.client.execute(req).await?;
188
189    let status = resp.status();
190
191    if !status.is_client_error() && !status.is_server_error() {
192        Ok(())
193    } else {
194        let content = resp.text().await?;
195        let entity: Option<BookAnalyzeError> = serde_json::from_str(&content).ok();
196        Err(Error::ResponseError(ResponseContent { status, content, entity }))
197    }
198}
199
200/// Required role: **ADMIN**
201pub async fn book_refresh_metadata(configuration: &configuration::Configuration, book_id: &str) -> Result<(), Error<BookRefreshMetadataError>> {
202    // add a prefix to parameters to efficiently prevent name collisions
203    let p_path_book_id = book_id;
204
205    let uri_str = format!("{}/api/v1/books/{bookId}/metadata/refresh", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
206    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
207
208    if let Some(ref user_agent) = configuration.user_agent {
209        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
210    }
211    if let Some(ref apikey) = configuration.api_key {
212        let key = apikey.key.clone();
213        let value = match apikey.prefix {
214            Some(ref prefix) => format!("{} {}", prefix, key),
215            None => key,
216        };
217        req_builder = req_builder.header("X-API-Key", value);
218    };
219    if let Some(ref auth_conf) = configuration.basic_auth {
220        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
221    };
222
223    let req = req_builder.build()?;
224    let resp = configuration.client.execute(req).await?;
225
226    let status = resp.status();
227
228    if !status.is_client_error() && !status.is_server_error() {
229        Ok(())
230    } else {
231        let content = resp.text().await?;
232        let entity: Option<BookRefreshMetadataError> = serde_json::from_str(&content).ok();
233        Err(Error::ResponseError(ResponseContent { status, content, entity }))
234    }
235}
236
237/// Required role: **ADMIN**
238pub async fn delete_book_file(configuration: &configuration::Configuration, book_id: &str) -> Result<(), Error<DeleteBookFileError>> {
239    // add a prefix to parameters to efficiently prevent name collisions
240    let p_path_book_id = book_id;
241
242    let uri_str = format!("{}/api/v1/books/{bookId}/file", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
243    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
244
245    if let Some(ref user_agent) = configuration.user_agent {
246        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
247    }
248    if let Some(ref apikey) = configuration.api_key {
249        let key = apikey.key.clone();
250        let value = match apikey.prefix {
251            Some(ref prefix) => format!("{} {}", prefix, key),
252            None => key,
253        };
254        req_builder = req_builder.header("X-API-Key", value);
255    };
256    if let Some(ref auth_conf) = configuration.basic_auth {
257        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
258    };
259
260    let req = req_builder.build()?;
261    let resp = configuration.client.execute(req).await?;
262
263    let status = resp.status();
264
265    if !status.is_client_error() && !status.is_server_error() {
266        Ok(())
267    } else {
268        let content = resp.text().await?;
269        let entity: Option<DeleteBookFileError> = serde_json::from_str(&content).ok();
270        Err(Error::ResponseError(ResponseContent { status, content, entity }))
271    }
272}
273
274/// Mark book as unread
275pub async fn delete_book_read_progress(configuration: &configuration::Configuration, book_id: &str) -> Result<(), Error<DeleteBookReadProgressError>> {
276    // add a prefix to parameters to efficiently prevent name collisions
277    let p_path_book_id = book_id;
278
279    let uri_str = format!("{}/api/v1/books/{bookId}/read-progress", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
280    let mut req_builder = configuration.client.request(reqwest::Method::DELETE, &uri_str);
281
282    if let Some(ref user_agent) = configuration.user_agent {
283        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
284    }
285    if let Some(ref apikey) = configuration.api_key {
286        let key = apikey.key.clone();
287        let value = match apikey.prefix {
288            Some(ref prefix) => format!("{} {}", prefix, key),
289            None => key,
290        };
291        req_builder = req_builder.header("X-API-Key", value);
292    };
293    if let Some(ref auth_conf) = configuration.basic_auth {
294        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
295    };
296
297    let req = req_builder.build()?;
298    let resp = configuration.client.execute(req).await?;
299
300    let status = resp.status();
301
302    if !status.is_client_error() && !status.is_server_error() {
303        Ok(())
304    } else {
305        let content = resp.text().await?;
306        let entity: Option<DeleteBookReadProgressError> = serde_json::from_str(&content).ok();
307        Err(Error::ResponseError(ResponseContent { status, content, entity }))
308    }
309}
310
311/// Download the book file.  Required role: **FILE_DOWNLOAD**
312pub async fn download_book_file(configuration: &configuration::Configuration, book_id: &str) -> Result<serde_json::Value, Error<DownloadBookFileError>> {
313    // add a prefix to parameters to efficiently prevent name collisions
314    let p_path_book_id = book_id;
315
316    let uri_str = format!("{}/api/v1/books/{bookId}/file", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
317    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
318
319    if let Some(ref user_agent) = configuration.user_agent {
320        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
321    }
322    if let Some(ref apikey) = configuration.api_key {
323        let key = apikey.key.clone();
324        let value = match apikey.prefix {
325            Some(ref prefix) => format!("{} {}", prefix, key),
326            None => key,
327        };
328        req_builder = req_builder.header("X-API-Key", value);
329    };
330    if let Some(ref auth_conf) = configuration.basic_auth {
331        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
332    };
333
334    let req = req_builder.build()?;
335    let resp = configuration.client.execute(req).await?;
336
337    let status = resp.status();
338    let content_type = resp
339        .headers()
340        .get("content-type")
341        .and_then(|v| v.to_str().ok())
342        .unwrap_or("application/octet-stream");
343    let content_type = super::ContentType::from(content_type);
344
345    if !status.is_client_error() && !status.is_server_error() {
346        let content = resp.text().await?;
347        match content_type {
348            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
349            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `serde_json::Value`"))),
350            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `serde_json::Value`")))),
351        }
352    } else {
353        let content = resp.text().await?;
354        let entity: Option<DownloadBookFileError> = serde_json::from_str(&content).ok();
355        Err(Error::ResponseError(ResponseContent { status, content, entity }))
356    }
357}
358
359/// Download the book file.  Required role: **FILE_DOWNLOAD**
360pub async fn download_book_file1(configuration: &configuration::Configuration, book_id: &str) -> Result<serde_json::Value, Error<DownloadBookFile1Error>> {
361    // add a prefix to parameters to efficiently prevent name collisions
362    let p_path_book_id = book_id;
363
364    let uri_str = format!("{}/api/v1/books/{bookId}/file/*", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
365    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
366
367    if let Some(ref user_agent) = configuration.user_agent {
368        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
369    }
370    if let Some(ref apikey) = configuration.api_key {
371        let key = apikey.key.clone();
372        let value = match apikey.prefix {
373            Some(ref prefix) => format!("{} {}", prefix, key),
374            None => key,
375        };
376        req_builder = req_builder.header("X-API-Key", value);
377    };
378    if let Some(ref auth_conf) = configuration.basic_auth {
379        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
380    };
381
382    let req = req_builder.build()?;
383    let resp = configuration.client.execute(req).await?;
384
385    let status = resp.status();
386    let content_type = resp
387        .headers()
388        .get("content-type")
389        .and_then(|v| v.to_str().ok())
390        .unwrap_or("application/octet-stream");
391    let content_type = super::ContentType::from(content_type);
392
393    if !status.is_client_error() && !status.is_server_error() {
394        let content = resp.text().await?;
395        match content_type {
396            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
397            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `serde_json::Value`"))),
398            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `serde_json::Value`")))),
399        }
400    } else {
401        let content = resp.text().await?;
402        let entity: Option<DownloadBookFile1Error> = serde_json::from_str(&content).ok();
403        Err(Error::ResponseError(ResponseContent { status, content, entity }))
404    }
405}
406
407/// Use POST /api/v1/books/list instead. Deprecated since 1.19.0.
408pub async fn get_all_books_deprecated(configuration: &configuration::Configuration, search: Option<&str>, library_id: Option<Vec<String>>, media_status: Option<Vec<String>>, read_status: Option<Vec<String>>, released_after: Option<String>, tag: Option<Vec<String>>, unpaged: Option<bool>, page: Option<i32>, size: Option<i32>, sort: Option<Vec<String>>) -> Result<models::PageBookDto, Error<GetAllBooksDeprecatedError>> {
409    // add a prefix to parameters to efficiently prevent name collisions
410    let p_query_search = search;
411    let p_query_library_id = library_id;
412    let p_query_media_status = media_status;
413    let p_query_read_status = read_status;
414    let p_query_released_after = released_after;
415    let p_query_tag = tag;
416    let p_query_unpaged = unpaged;
417    let p_query_page = page;
418    let p_query_size = size;
419    let p_query_sort = sort;
420
421    let uri_str = format!("{}/api/v1/books", configuration.base_path);
422    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
423
424    if let Some(ref param_value) = p_query_search {
425        req_builder = req_builder.query(&[("search", &param_value.to_string())]);
426    }
427    if let Some(ref param_value) = p_query_library_id {
428        req_builder = match "multi" {
429            "multi" => req_builder.query(&param_value.into_iter().map(|p| ("library_id".to_owned(), p.to_string())).collect::<Vec<(std::string::String, std::string::String)>>()),
430            _ => req_builder.query(&[("library_id", &param_value.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(",").to_string())]),
431        };
432    }
433    if let Some(ref param_value) = p_query_media_status {
434        req_builder = match "multi" {
435            "multi" => req_builder.query(&param_value.into_iter().map(|p| ("media_status".to_owned(), p.to_string())).collect::<Vec<(std::string::String, std::string::String)>>()),
436            _ => req_builder.query(&[("media_status", &param_value.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(",").to_string())]),
437        };
438    }
439    if let Some(ref param_value) = p_query_read_status {
440        req_builder = match "multi" {
441            "multi" => req_builder.query(&param_value.into_iter().map(|p| ("read_status".to_owned(), p.to_string())).collect::<Vec<(std::string::String, std::string::String)>>()),
442            _ => req_builder.query(&[("read_status", &param_value.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(",").to_string())]),
443        };
444    }
445    if let Some(ref param_value) = p_query_released_after {
446        req_builder = req_builder.query(&[("released_after", &param_value.to_string())]);
447    }
448    if let Some(ref param_value) = p_query_tag {
449        req_builder = match "multi" {
450            "multi" => req_builder.query(&param_value.into_iter().map(|p| ("tag".to_owned(), p.to_string())).collect::<Vec<(std::string::String, std::string::String)>>()),
451            _ => req_builder.query(&[("tag", &param_value.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(",").to_string())]),
452        };
453    }
454    if let Some(ref param_value) = p_query_unpaged {
455        req_builder = req_builder.query(&[("unpaged", &param_value.to_string())]);
456    }
457    if let Some(ref param_value) = p_query_page {
458        req_builder = req_builder.query(&[("page", &param_value.to_string())]);
459    }
460    if let Some(ref param_value) = p_query_size {
461        req_builder = req_builder.query(&[("size", &param_value.to_string())]);
462    }
463    if let Some(ref param_value) = p_query_sort {
464        req_builder = match "multi" {
465            "multi" => req_builder.query(&param_value.into_iter().map(|p| ("sort".to_owned(), p.to_string())).collect::<Vec<(std::string::String, std::string::String)>>()),
466            _ => req_builder.query(&[("sort", &param_value.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(",").to_string())]),
467        };
468    }
469    if let Some(ref user_agent) = configuration.user_agent {
470        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
471    }
472    if let Some(ref apikey) = configuration.api_key {
473        let key = apikey.key.clone();
474        let value = match apikey.prefix {
475            Some(ref prefix) => format!("{} {}", prefix, key),
476            None => key,
477        };
478        req_builder = req_builder.header("X-API-Key", value);
479    };
480    if let Some(ref auth_conf) = configuration.basic_auth {
481        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
482    };
483
484    let req = req_builder.build()?;
485    let resp = configuration.client.execute(req).await?;
486
487    let status = resp.status();
488    let content_type = resp
489        .headers()
490        .get("content-type")
491        .and_then(|v| v.to_str().ok())
492        .unwrap_or("application/octet-stream");
493    let content_type = super::ContentType::from(content_type);
494
495    if !status.is_client_error() && !status.is_server_error() {
496        let content = resp.text().await?;
497        match content_type {
498            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
499            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PageBookDto`"))),
500            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PageBookDto`")))),
501        }
502    } else {
503        let content = resp.text().await?;
504        let entity: Option<GetAllBooksDeprecatedError> = serde_json::from_str(&content).ok();
505        Err(Error::ResponseError(ResponseContent { status, content, entity }))
506    }
507}
508
509pub async fn get_book_by_id(configuration: &configuration::Configuration, book_id: &str) -> Result<models::BookDto, Error<GetBookByIdError>> {
510    // add a prefix to parameters to efficiently prevent name collisions
511    let p_path_book_id = book_id;
512
513    let uri_str = format!("{}/api/v1/books/{bookId}", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
514    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
515
516    if let Some(ref user_agent) = configuration.user_agent {
517        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
518    }
519    if let Some(ref apikey) = configuration.api_key {
520        let key = apikey.key.clone();
521        let value = match apikey.prefix {
522            Some(ref prefix) => format!("{} {}", prefix, key),
523            None => key,
524        };
525        req_builder = req_builder.header("X-API-Key", value);
526    };
527    if let Some(ref auth_conf) = configuration.basic_auth {
528        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
529    };
530
531    let req = req_builder.build()?;
532    let resp = configuration.client.execute(req).await?;
533
534    let status = resp.status();
535    let content_type = resp
536        .headers()
537        .get("content-type")
538        .and_then(|v| v.to_str().ok())
539        .unwrap_or("application/octet-stream");
540    let content_type = super::ContentType::from(content_type);
541
542    if !status.is_client_error() && !status.is_server_error() {
543        let content = resp.text().await?;
544        match content_type {
545            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
546            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BookDto`"))),
547            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BookDto`")))),
548        }
549    } else {
550        let content = resp.text().await?;
551        let entity: Option<GetBookByIdError> = serde_json::from_str(&content).ok();
552        Err(Error::ResponseError(ResponseContent { status, content, entity }))
553    }
554}
555
556pub async fn get_book_sibling_next(configuration: &configuration::Configuration, book_id: &str) -> Result<models::BookDto, Error<GetBookSiblingNextError>> {
557    // add a prefix to parameters to efficiently prevent name collisions
558    let p_path_book_id = book_id;
559
560    let uri_str = format!("{}/api/v1/books/{bookId}/next", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
561    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
562
563    if let Some(ref user_agent) = configuration.user_agent {
564        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
565    }
566    if let Some(ref apikey) = configuration.api_key {
567        let key = apikey.key.clone();
568        let value = match apikey.prefix {
569            Some(ref prefix) => format!("{} {}", prefix, key),
570            None => key,
571        };
572        req_builder = req_builder.header("X-API-Key", value);
573    };
574    if let Some(ref auth_conf) = configuration.basic_auth {
575        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
576    };
577
578    let req = req_builder.build()?;
579    let resp = configuration.client.execute(req).await?;
580
581    let status = resp.status();
582    let content_type = resp
583        .headers()
584        .get("content-type")
585        .and_then(|v| v.to_str().ok())
586        .unwrap_or("application/octet-stream");
587    let content_type = super::ContentType::from(content_type);
588
589    if !status.is_client_error() && !status.is_server_error() {
590        let content = resp.text().await?;
591        match content_type {
592            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
593            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BookDto`"))),
594            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BookDto`")))),
595        }
596    } else {
597        let content = resp.text().await?;
598        let entity: Option<GetBookSiblingNextError> = serde_json::from_str(&content).ok();
599        Err(Error::ResponseError(ResponseContent { status, content, entity }))
600    }
601}
602
603pub async fn get_book_sibling_previous(configuration: &configuration::Configuration, book_id: &str) -> Result<models::BookDto, Error<GetBookSiblingPreviousError>> {
604    // add a prefix to parameters to efficiently prevent name collisions
605    let p_path_book_id = book_id;
606
607    let uri_str = format!("{}/api/v1/books/{bookId}/previous", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
608    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
609
610    if let Some(ref user_agent) = configuration.user_agent {
611        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
612    }
613    if let Some(ref apikey) = configuration.api_key {
614        let key = apikey.key.clone();
615        let value = match apikey.prefix {
616            Some(ref prefix) => format!("{} {}", prefix, key),
617            None => key,
618        };
619        req_builder = req_builder.header("X-API-Key", value);
620    };
621    if let Some(ref auth_conf) = configuration.basic_auth {
622        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
623    };
624
625    let req = req_builder.build()?;
626    let resp = configuration.client.execute(req).await?;
627
628    let status = resp.status();
629    let content_type = resp
630        .headers()
631        .get("content-type")
632        .and_then(|v| v.to_str().ok())
633        .unwrap_or("application/octet-stream");
634    let content_type = super::ContentType::from(content_type);
635
636    if !status.is_client_error() && !status.is_server_error() {
637        let content = resp.text().await?;
638        match content_type {
639            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
640            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BookDto`"))),
641            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BookDto`")))),
642        }
643    } else {
644        let content = resp.text().await?;
645        let entity: Option<GetBookSiblingPreviousError> = serde_json::from_str(&content).ok();
646        Err(Error::ResponseError(ResponseContent { status, content, entity }))
647    }
648}
649
650pub async fn get_books(configuration: &configuration::Configuration, book_search: models::BookSearch, unpaged: Option<bool>, page: Option<i32>, size: Option<i32>, sort: Option<Vec<String>>) -> Result<models::PageBookDto, Error<GetBooksError>> {
651    // add a prefix to parameters to efficiently prevent name collisions
652    let p_body_book_search = book_search;
653    let p_query_unpaged = unpaged;
654    let p_query_page = page;
655    let p_query_size = size;
656    let p_query_sort = sort;
657
658    let uri_str = format!("{}/api/v1/books/list", configuration.base_path);
659    let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
660
661    if let Some(ref param_value) = p_query_unpaged {
662        req_builder = req_builder.query(&[("unpaged", &param_value.to_string())]);
663    }
664    if let Some(ref param_value) = p_query_page {
665        req_builder = req_builder.query(&[("page", &param_value.to_string())]);
666    }
667    if let Some(ref param_value) = p_query_size {
668        req_builder = req_builder.query(&[("size", &param_value.to_string())]);
669    }
670    if let Some(ref param_value) = p_query_sort {
671        req_builder = match "multi" {
672            "multi" => req_builder.query(&param_value.into_iter().map(|p| ("sort".to_owned(), p.to_string())).collect::<Vec<(std::string::String, std::string::String)>>()),
673            _ => req_builder.query(&[("sort", &param_value.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(",").to_string())]),
674        };
675    }
676    if let Some(ref user_agent) = configuration.user_agent {
677        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
678    }
679    if let Some(ref apikey) = configuration.api_key {
680        let key = apikey.key.clone();
681        let value = match apikey.prefix {
682            Some(ref prefix) => format!("{} {}", prefix, key),
683            None => key,
684        };
685        req_builder = req_builder.header("X-API-Key", value);
686    };
687    if let Some(ref auth_conf) = configuration.basic_auth {
688        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
689    };
690    req_builder = req_builder.json(&p_body_book_search);
691
692    let req = req_builder.build()?;
693    let resp = configuration.client.execute(req).await?;
694
695    let status = resp.status();
696    let content_type = resp
697        .headers()
698        .get("content-type")
699        .and_then(|v| v.to_str().ok())
700        .unwrap_or("application/octet-stream");
701    let content_type = super::ContentType::from(content_type);
702
703    if !status.is_client_error() && !status.is_server_error() {
704        let content = resp.text().await?;
705        match content_type {
706            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
707            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PageBookDto`"))),
708            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PageBookDto`")))),
709        }
710    } else {
711        let content = resp.text().await?;
712        let entity: Option<GetBooksError> = serde_json::from_str(&content).ok();
713        Err(Error::ResponseError(ResponseContent { status, content, entity }))
714    }
715}
716
717/// Return books that have the same file hash.  Required role: **ADMIN**
718pub async fn get_books_duplicates(configuration: &configuration::Configuration, unpaged: Option<bool>, page: Option<i32>, size: Option<i32>, sort: Option<Vec<String>>) -> Result<models::PageBookDto, Error<GetBooksDuplicatesError>> {
719    // add a prefix to parameters to efficiently prevent name collisions
720    let p_query_unpaged = unpaged;
721    let p_query_page = page;
722    let p_query_size = size;
723    let p_query_sort = sort;
724
725    let uri_str = format!("{}/api/v1/books/duplicates", configuration.base_path);
726    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
727
728    if let Some(ref param_value) = p_query_unpaged {
729        req_builder = req_builder.query(&[("unpaged", &param_value.to_string())]);
730    }
731    if let Some(ref param_value) = p_query_page {
732        req_builder = req_builder.query(&[("page", &param_value.to_string())]);
733    }
734    if let Some(ref param_value) = p_query_size {
735        req_builder = req_builder.query(&[("size", &param_value.to_string())]);
736    }
737    if let Some(ref param_value) = p_query_sort {
738        req_builder = match "multi" {
739            "multi" => req_builder.query(&param_value.into_iter().map(|p| ("sort".to_owned(), p.to_string())).collect::<Vec<(std::string::String, std::string::String)>>()),
740            _ => req_builder.query(&[("sort", &param_value.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(",").to_string())]),
741        };
742    }
743    if let Some(ref user_agent) = configuration.user_agent {
744        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
745    }
746    if let Some(ref apikey) = configuration.api_key {
747        let key = apikey.key.clone();
748        let value = match apikey.prefix {
749            Some(ref prefix) => format!("{} {}", prefix, key),
750            None => key,
751        };
752        req_builder = req_builder.header("X-API-Key", value);
753    };
754    if let Some(ref auth_conf) = configuration.basic_auth {
755        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
756    };
757
758    let req = req_builder.build()?;
759    let resp = configuration.client.execute(req).await?;
760
761    let status = resp.status();
762    let content_type = resp
763        .headers()
764        .get("content-type")
765        .and_then(|v| v.to_str().ok())
766        .unwrap_or("application/octet-stream");
767    let content_type = super::ContentType::from(content_type);
768
769    if !status.is_client_error() && !status.is_server_error() {
770        let content = resp.text().await?;
771        match content_type {
772            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
773            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PageBookDto`"))),
774            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PageBookDto`")))),
775        }
776    } else {
777        let content = resp.text().await?;
778        let entity: Option<GetBooksDuplicatesError> = serde_json::from_str(&content).ok();
779        Err(Error::ResponseError(ResponseContent { status, content, entity }))
780    }
781}
782
783/// Return newly added or updated books.
784pub async fn get_books_latest(configuration: &configuration::Configuration, unpaged: Option<bool>, page: Option<i32>, size: Option<i32>) -> Result<models::PageBookDto, Error<GetBooksLatestError>> {
785    // add a prefix to parameters to efficiently prevent name collisions
786    let p_query_unpaged = unpaged;
787    let p_query_page = page;
788    let p_query_size = size;
789
790    let uri_str = format!("{}/api/v1/books/latest", configuration.base_path);
791    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
792
793    if let Some(ref param_value) = p_query_unpaged {
794        req_builder = req_builder.query(&[("unpaged", &param_value.to_string())]);
795    }
796    if let Some(ref param_value) = p_query_page {
797        req_builder = req_builder.query(&[("page", &param_value.to_string())]);
798    }
799    if let Some(ref param_value) = p_query_size {
800        req_builder = req_builder.query(&[("size", &param_value.to_string())]);
801    }
802    if let Some(ref user_agent) = configuration.user_agent {
803        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
804    }
805    if let Some(ref apikey) = configuration.api_key {
806        let key = apikey.key.clone();
807        let value = match apikey.prefix {
808            Some(ref prefix) => format!("{} {}", prefix, key),
809            None => key,
810        };
811        req_builder = req_builder.header("X-API-Key", value);
812    };
813    if let Some(ref auth_conf) = configuration.basic_auth {
814        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
815    };
816
817    let req = req_builder.build()?;
818    let resp = configuration.client.execute(req).await?;
819
820    let status = resp.status();
821    let content_type = resp
822        .headers()
823        .get("content-type")
824        .and_then(|v| v.to_str().ok())
825        .unwrap_or("application/octet-stream");
826    let content_type = super::ContentType::from(content_type);
827
828    if !status.is_client_error() && !status.is_server_error() {
829        let content = resp.text().await?;
830        match content_type {
831            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
832            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PageBookDto`"))),
833            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PageBookDto`")))),
834        }
835    } else {
836        let content = resp.text().await?;
837        let entity: Option<GetBooksLatestError> = serde_json::from_str(&content).ok();
838        Err(Error::ResponseError(ResponseContent { status, content, entity }))
839    }
840}
841
842/// Return first unread book of series with at least one book read and no books in progress.
843pub async fn get_books_on_deck(configuration: &configuration::Configuration, library_id: Option<Vec<String>>, page: Option<i32>, size: Option<i32>) -> Result<models::PageBookDto, Error<GetBooksOnDeckError>> {
844    // add a prefix to parameters to efficiently prevent name collisions
845    let p_query_library_id = library_id;
846    let p_query_page = page;
847    let p_query_size = size;
848
849    let uri_str = format!("{}/api/v1/books/ondeck", configuration.base_path);
850    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
851
852    if let Some(ref param_value) = p_query_library_id {
853        req_builder = match "multi" {
854            "multi" => req_builder.query(&param_value.into_iter().map(|p| ("library_id".to_owned(), p.to_string())).collect::<Vec<(std::string::String, std::string::String)>>()),
855            _ => req_builder.query(&[("library_id", &param_value.into_iter().map(|p| p.to_string()).collect::<Vec<String>>().join(",").to_string())]),
856        };
857    }
858    if let Some(ref param_value) = p_query_page {
859        req_builder = req_builder.query(&[("page", &param_value.to_string())]);
860    }
861    if let Some(ref param_value) = p_query_size {
862        req_builder = req_builder.query(&[("size", &param_value.to_string())]);
863    }
864    if let Some(ref user_agent) = configuration.user_agent {
865        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
866    }
867    if let Some(ref apikey) = configuration.api_key {
868        let key = apikey.key.clone();
869        let value = match apikey.prefix {
870            Some(ref prefix) => format!("{} {}", prefix, key),
871            None => key,
872        };
873        req_builder = req_builder.header("X-API-Key", value);
874    };
875    if let Some(ref auth_conf) = configuration.basic_auth {
876        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
877    };
878
879    let req = req_builder.build()?;
880    let resp = configuration.client.execute(req).await?;
881
882    let status = resp.status();
883    let content_type = resp
884        .headers()
885        .get("content-type")
886        .and_then(|v| v.to_str().ok())
887        .unwrap_or("application/octet-stream");
888    let content_type = super::ContentType::from(content_type);
889
890    if !status.is_client_error() && !status.is_server_error() {
891        let content = resp.text().await?;
892        match content_type {
893            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
894            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PageBookDto`"))),
895            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PageBookDto`")))),
896        }
897    } else {
898        let content = resp.text().await?;
899        let entity: Option<GetBooksOnDeckError> = serde_json::from_str(&content).ok();
900        Err(Error::ResponseError(ResponseContent { status, content, entity }))
901    }
902}
903
904pub async fn get_read_lists_by_book_id(configuration: &configuration::Configuration, book_id: &str) -> Result<Vec<models::ReadListDto>, Error<GetReadListsByBookIdError>> {
905    // add a prefix to parameters to efficiently prevent name collisions
906    let p_path_book_id = book_id;
907
908    let uri_str = format!("{}/api/v1/books/{bookId}/readlists", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
909    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
910
911    if let Some(ref user_agent) = configuration.user_agent {
912        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
913    }
914    if let Some(ref apikey) = configuration.api_key {
915        let key = apikey.key.clone();
916        let value = match apikey.prefix {
917            Some(ref prefix) => format!("{} {}", prefix, key),
918            None => key,
919        };
920        req_builder = req_builder.header("X-API-Key", value);
921    };
922    if let Some(ref auth_conf) = configuration.basic_auth {
923        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
924    };
925
926    let req = req_builder.build()?;
927    let resp = configuration.client.execute(req).await?;
928
929    let status = resp.status();
930    let content_type = resp
931        .headers()
932        .get("content-type")
933        .and_then(|v| v.to_str().ok())
934        .unwrap_or("application/octet-stream");
935    let content_type = super::ContentType::from(content_type);
936
937    if !status.is_client_error() && !status.is_server_error() {
938        let content = resp.text().await?;
939        match content_type {
940            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
941            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `Vec&lt;models::ReadListDto&gt;`"))),
942            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `Vec&lt;models::ReadListDto&gt;`")))),
943        }
944    } else {
945        let content = resp.text().await?;
946        let entity: Option<GetReadListsByBookIdError> = serde_json::from_str(&content).ok();
947        Err(Error::ResponseError(ResponseContent { status, content, entity }))
948    }
949}
950
951/// Mark book as read and/or change page progress.
952pub async fn mark_book_read_progress(configuration: &configuration::Configuration, book_id: &str, read_progress_update_dto: models::ReadProgressUpdateDto) -> Result<(), Error<MarkBookReadProgressError>> {
953    // add a prefix to parameters to efficiently prevent name collisions
954    let p_path_book_id = book_id;
955    let p_body_read_progress_update_dto = read_progress_update_dto;
956
957    let uri_str = format!("{}/api/v1/books/{bookId}/read-progress", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
958    let mut req_builder = configuration.client.request(reqwest::Method::PATCH, &uri_str);
959
960    if let Some(ref user_agent) = configuration.user_agent {
961        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
962    }
963    if let Some(ref apikey) = configuration.api_key {
964        let key = apikey.key.clone();
965        let value = match apikey.prefix {
966            Some(ref prefix) => format!("{} {}", prefix, key),
967            None => key,
968        };
969        req_builder = req_builder.header("X-API-Key", value);
970    };
971    if let Some(ref auth_conf) = configuration.basic_auth {
972        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
973    };
974    req_builder = req_builder.json(&p_body_read_progress_update_dto);
975
976    let req = req_builder.build()?;
977    let resp = configuration.client.execute(req).await?;
978
979    let status = resp.status();
980
981    if !status.is_client_error() && !status.is_server_error() {
982        Ok(())
983    } else {
984        let content = resp.text().await?;
985        let entity: Option<MarkBookReadProgressError> = serde_json::from_str(&content).ok();
986        Err(Error::ResponseError(ResponseContent { status, content, entity }))
987    }
988}
989
990/// Set a field to null to unset the metadata. You can omit fields you don't want to update.  Required role: **ADMIN**
991pub async fn update_book_metadata(configuration: &configuration::Configuration, book_id: &str, book_metadata_update_dto: models::BookMetadataUpdateDto) -> Result<(), Error<UpdateBookMetadataError>> {
992    // add a prefix to parameters to efficiently prevent name collisions
993    let p_path_book_id = book_id;
994    let p_body_book_metadata_update_dto = book_metadata_update_dto;
995
996    let uri_str = format!("{}/api/v1/books/{bookId}/metadata", configuration.base_path, bookId=crate::apis::urlencode(p_path_book_id));
997    let mut req_builder = configuration.client.request(reqwest::Method::PATCH, &uri_str);
998
999    if let Some(ref user_agent) = configuration.user_agent {
1000        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1001    }
1002    if let Some(ref apikey) = configuration.api_key {
1003        let key = apikey.key.clone();
1004        let value = match apikey.prefix {
1005            Some(ref prefix) => format!("{} {}", prefix, key),
1006            None => key,
1007        };
1008        req_builder = req_builder.header("X-API-Key", value);
1009    };
1010    if let Some(ref auth_conf) = configuration.basic_auth {
1011        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
1012    };
1013    req_builder = req_builder.json(&p_body_book_metadata_update_dto);
1014
1015    let req = req_builder.build()?;
1016    let resp = configuration.client.execute(req).await?;
1017
1018    let status = resp.status();
1019
1020    if !status.is_client_error() && !status.is_server_error() {
1021        Ok(())
1022    } else {
1023        let content = resp.text().await?;
1024        let entity: Option<UpdateBookMetadataError> = serde_json::from_str(&content).ok();
1025        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1026    }
1027}
1028
1029/// Set a field to null to unset the metadata. You can omit fields you don't want to update.  Required role: **ADMIN**
1030pub async fn update_book_metadata_by_batch(configuration: &configuration::Configuration, request_body: std::collections::HashMap<String, models::BookMetadataUpdateDto>) -> Result<(), Error<UpdateBookMetadataByBatchError>> {
1031    // add a prefix to parameters to efficiently prevent name collisions
1032    let p_body_request_body = request_body;
1033
1034    let uri_str = format!("{}/api/v1/books/metadata", configuration.base_path);
1035    let mut req_builder = configuration.client.request(reqwest::Method::PATCH, &uri_str);
1036
1037    if let Some(ref user_agent) = configuration.user_agent {
1038        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
1039    }
1040    if let Some(ref apikey) = configuration.api_key {
1041        let key = apikey.key.clone();
1042        let value = match apikey.prefix {
1043            Some(ref prefix) => format!("{} {}", prefix, key),
1044            None => key,
1045        };
1046        req_builder = req_builder.header("X-API-Key", value);
1047    };
1048    if let Some(ref auth_conf) = configuration.basic_auth {
1049        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
1050    };
1051    req_builder = req_builder.json(&p_body_request_body);
1052
1053    let req = req_builder.build()?;
1054    let resp = configuration.client.execute(req).await?;
1055
1056    let status = resp.status();
1057
1058    if !status.is_client_error() && !status.is_server_error() {
1059        Ok(())
1060    } else {
1061        let content = resp.text().await?;
1062        let entity: Option<UpdateBookMetadataByBatchError> = serde_json::from_str(&content).ok();
1063        Err(Error::ResponseError(ResponseContent { status, content, entity }))
1064    }
1065}
1066