# MangaDex API
Unofficial Rust client/wrapper for the MangaDex API.
This also includes some conveniences that are not provided from the API directly such as logging in.
*Warning:
This is still in the **early development stage**.
Some breaking API changes may occur as the project matures.
Consequently, this code is not yet ready for use in production.*
# Table of Contents
* [Requirements][readme-section-requirements]
* [Features][readme-section-features]
* [Optional Features][readme-section-optional-features]
* [Examples][readme-section-examples]
* [Running Examples][readme-section-running-examples]
* [License][readme-section-license]
* [Contribution][readme-section-contribution]
* [Contributing][readme-section-contributing]
# Requirements
[Back to top][readme-section-toc]
* [Rust 1.47+][rust-homepage]
# Features
[Back to top][readme-section-toc]
* [v2 support][mangadex-v2-api-index]
* [OpenAPI Document (Unofficial)][mangadex-v2-openapi-spec]
# Optional Features
[Back to top][readme-section-toc]
* `time` - Use [Chrono][chrono-docs] for the timestamps instead of integers and arbitrary strings.
Included by default.
# Examples
[Back to top][readme-section-toc]
### Fetch manga by ID
```rust
use mangadex_api::v2::{responses::ResponseType, MangaDexV2};
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let mangadex_client = MangaDexV2::default();
let manga = mangadex_client
.manga(1)
.send()
.await?
.ok()
.unwrap();
// Fields are hidden behind getter methods to prevent field mutation.
// The getters return a referenced value so comparisons require de-referencing.
assert_eq!(*manga.data().id(), 1);
Ok(())
}
```
### Logging in
Some features on MangaDex are restricted to registered users such as searching by manga title.
In order to use these features, you must log in first and the [`Reqwest` library][reqwest-library]
will store the session cookie in the client. Once that's done, you can use call the other endpoints
normally and get the data you need.
```rust
use std::io;
use mangadex_api::v2::MangaDexV2;
use mangadex_api::web_scrape::responses::LoginAjaxResponseType;
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let mangadex_client = MangaDexV2::default();
let mut username = String::new();
println!("Enter your MangaDex username:");
io::stdin()
.read_line(&mut username)
.expect("Failed to read username");
let mut password = String::new();
println!("Enter your MangaDex password:");
io::stdin()
.read_line(&mut password)
.expect("Failed to read password");
// If you know that you need a 2-factor authentication code, you can add it directly before
// sending the first login attempt and not check the `TwoFactorAuthenticationRequired` variant.
match mangadex_client
.login_ajax(&username, &password)
.send()
.await?
{
LoginAjaxResponseType::Ok => {
println!("Login successful!")
}
LoginAjaxResponseType::TwoFactorAuthenticationRequired => {
let mut two_factor = String::new();
loop {
println!("Enter your 2FA code:");
io::stdin()
.read_line(&mut two_factor)
.expect("Failed to read 2FA code");
match mangadex_client
.login_ajax(&username, &password)
.two_factor(&two_factor)
.send()
.await?
{
LoginAjaxResponseType::Ok => {
println!("Login successful!");
break;
}
LoginAjaxResponseType::IncorrectTwoFactorCodeLength
| LoginAjaxResponseType::FailedTwoFactorVerification => {
println!("Incorrect 2FA code")
}
_ => panic!("There was an error submitting the 2FA code"),
}
}
}
_ => panic!("There was an error logging in."),
}
Ok(())
}
```
# Running Examples
[Back to top][readme-section-toc]
The examples can be run with the following:
```
cargo run --example [example_name]
```
More details about the examples can be found in the [examples README][examples-readme] file.
# Changelog
[Back to top][readme-section-toc]
The changelog can be found [here][changelog].
Changes are added manually to keep the changelog human-readable with summaries of the changes from each version.
# License
[Back to top][readme-section-toc]
Licensed under either of
* Apache License, Version 2.0
([LICENSE-APACHE][license-apache] or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license
([LICENSE-MIT][license-mit] or http://opensource.org/licenses/MIT)
at your option.
## Contribution
[Back to top][readme-section-toc]
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.
# Contributing
[Back to top][readme-section-toc]
We welcome contributions from everyone. There are many ways to contribute and the
[CONTRIBUTING.md][contributing] document explains how you can contribute and get started.
[changelog]: CHANGELOG.md
[chrono-docs]: https://docs.rs/chrono
[contributing]: CONTRIBUTING.md
[examples-readme]: examples/README.md
[license-apache]: LICENSE-APACHE
[license-mit]: LICENSE-MIT
[mangadex-v2-api-index]: https://api.mangadex.org/v2
[mangadex-v2-openapi-spec]: src/v2/openapi.yaml
[readme-section-contributing]: #contributing
[readme-section-contribution]: #contribution
[readme-section-examples]: #examples
[readme-section-features]: #features
[readme-section-license]: #license
[readme-section-requirements]: #requirements
[readme-section-running-examples]: #running-examples
[readme-section-optional-features]: #optional-features
[readme-requirements]: #requirements
[readme-section-toc]: #table-of-contents
[reqwest-library]: https://crates.io/crates/reqwest
[rust-homepage]: https://rust-lang.org