#anime #mal #manga #my-anime-list #async #api-bindings #access-token

mal-api

An asynchronous MyAnimeList (MAL) API library for Rust

6 releases (stable)

2.0.2 May 10, 2024
2.0.1 May 9, 2024
2.0.0 Mar 4, 2024
1.0.0 Jan 2, 2024
0.1.0 Jul 21, 2023

#339 in Asynchronous

MIT license

185KB
4.5K SLoC

mal-api

An asynchronous MyAnimeList (MAL) API library for Rust.

Features

  • Type-safe query builder
  • Type-safe responses
  • Pagination through responses
  • Support for accessing all of MAL's endpoints (Anime, Manga, Forum, and User)
    • To access the Forum and User endpoints, enable the forum and user features
  • OAuth2 access token retrieval and management

Example

use dotenvy;
use mal_api::anime_common_fields;
use mal_api::oauth::MalClientId;
use mal_api::prelude::*;

#[tokio::main]
async fn main() {
    // See the .env.example for which 
    // environment variables you are expected to define
    dotenvy::dotenv().ok();

    let client_id = MalClientId::try_from_env().unwrap();

    let api_client = AnimeApiClient::from(&client_id);
    let fields = anime_common_fields!(
        AnimeField::id, 
        AnimeField::num_episodes, 
        AnimeField::title,
    );

    // Example using the builder pattern. 
    // The `builder(args...)` method will only take
    // the required arguments for the specific API endpoint, while the
    // other builder instance methods will build up the optional arguments
    let query = GetAnimeList::builder("One")
        .fields(&fields)
        .limit(5)
        .build()
        .unwrap();
    let result = api_client.get_anime_list(&query).await.unwrap();
    println!("Received response: {}", result);
    for entry in result.data.iter() {
        println!("Anime Title: {}  Anime ID: {}", entry.node.title, entry.node.id);
    }

    // Example iterating through pages
    let result = api_client.next(&result).await.unwrap();
    println!("Next result: {}", &result);

    let result = api_client.prev(&result).await.unwrap();
    println!("Prev result: {}", &result);

    // Manga API example
    let api_client = MangaApiClient::from(&client_id);
    let fields = mal_api::manga::all_common_fields();

    // Example using `new` pattern. Not recommended, but available
    let nsfw = false;
    let limit = Some(5);
    let query = GetMangaList::new("one", nsfw, Some(&fields), limit, None).unwrap();
    let result = api_client.get_manga_list(&query).await.unwrap();
    println!("Result: {}", result);
}

You can check out the examples directory to see additional usage examples.

Notes

Not all variants for particular fields are documented in the MAL API specification. This is expected since the MAL v2 API is still in beta. If a request fails because of an unexpected variant, please open an issue and describe what query you submitted which revealed the new variant.

License

This project is licensed under the MIT license

Dependencies

~6–18MB
~268K SLoC