add anime endpoint

This commit is contained in:
Dmitriy Kholkin 2025-01-09 21:10:13 +03:00
parent 87fbcd53b1
commit 27ccb918bf
Signed by: AtaraxiaDev
GPG Key ID: FD266B810DF48DF2
23 changed files with 859 additions and 0 deletions

View File

@ -1,3 +1,4 @@
pub mod anime;
mod client;
mod endpoint;
mod error;

46
src/api/anime.rs Normal file
View File

@ -0,0 +1,46 @@
#[allow(clippy::module_inception)]
mod anime;
mod anime_full;
mod characters;
mod episode;
mod episodes;
mod external;
mod forum;
mod more_info;
mod news;
mod pictures;
mod recommendations;
mod relations;
mod reviews;
mod search;
mod staff;
mod statistics;
mod streaming;
mod themes;
mod user_updates;
mod videos;
mod videos_episodes;
pub use self::{
anime::*,
anime_full::*,
characters::*,
episode::*,
episodes::*,
external::*,
forum::*,
more_info::*,
news::*,
pictures::*,
recommendations::*,
relations::*,
reviews::*,
search::*,
staff::*,
statistics::*,
streaming::*,
themes::*,
user_updates::*,
videos::*,
videos_episodes::*,
};

30
src/api/anime/anime.rs Normal file
View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime resource data.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Anime {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Anime {
/// Create a builder for this endpoint.
pub fn builder() -> AnimeBuilder {
AnimeBuilder::default()
}
}
impl Endpoint for Anime {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}", self.id).into()
}
}

View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves a complete anime resource data.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct AnimeFull {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl AnimeFull {
/// Create a builder for this endpoint.
pub fn builder() -> AnimeFullBuilder {
AnimeFullBuilder::default()
}
}
impl Endpoint for AnimeFull {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/full", self.id).into()
}
}

View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime characters resource.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Characters {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Characters {
/// Create a builder for this endpoint.
pub fn builder() -> CharactersBuilder {
CharactersBuilder::default()
}
}
impl Endpoint for Characters {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/characters", self.id).into()
}
}

32
src/api/anime/episode.rs Normal file
View File

@ -0,0 +1,32 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves an anime episode resource.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Episode {
#[doc = r"`ID` of the anime"]
id: u32,
#[doc = r"`ID` of the episode"]
episode: u32,
}
impl Episode {
/// Create a builder for this endpoint.
pub fn builder() -> EpisodeBuilder {
EpisodeBuilder::default()
}
}
impl Endpoint for Episode {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/episodes/{}", self.id, self.episode).into()
}
}

35
src/api/anime/episodes.rs Normal file
View File

@ -0,0 +1,35 @@
use std::borrow::Cow;
use http::Method;
use crate::api::{
endpoint::Endpoint,
page::Pageable,
};
/// Retrieves a list of anime episodes.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Episodes {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Episodes {
/// Create a builder for this endpoint.
pub fn builder() -> EpisodesBuilder {
EpisodesBuilder::default()
}
}
impl Endpoint for Episodes {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/episodes", self.id).into()
}
}
impl Pageable for Episodes {}

30
src/api/anime/external.rs Normal file
View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime external links.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct External {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl External {
/// Create a builder for this endpoint.
pub fn builder() -> ExternalBuilder {
ExternalBuilder::default()
}
}
impl Endpoint for External {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/external", self.id).into()
}
}

52
src/api/anime/forum.rs Normal file
View File

@ -0,0 +1,52 @@
use std::borrow::Cow;
use http::Method;
use serde::Serialize;
use crate::api::{
Query,
endpoint::Endpoint,
error::BodyError,
query_params::QueryParams,
};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize)]
#[serde(rename_all = "snake_case")]
enum ForumFilter {
All,
Episode,
Other,
}
/// Retrieves a list of forum topics related to the entry.
#[derive(Debug, Clone, Builder, Serialize)]
#[builder(setter(into))]
pub struct Forum {
#[doc = r"`ID` of the anime"]
#[serde(skip)]
id: u32,
#[doc = r"Filter forum topics"]
#[builder(default, setter(strip_option))]
filter: Option<ForumFilter>,
}
impl Forum {
/// Create a builder for this endpoint.
pub fn builder() -> ForumBuilder {
ForumBuilder::default()
}
}
impl Endpoint for Forum {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/forum", self.id).into()
}
fn query_params(&self) -> Result<QueryParams<'_>, BodyError> {
QueryParams::with(self)
}
}

View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime statistics.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct MoreInfo {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl MoreInfo {
/// Create a builder for this endpoint.
pub fn builder() -> MoreInfoBuilder {
MoreInfoBuilder::default()
}
}
impl Endpoint for MoreInfo {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/moreinfo", self.id).into()
}
}

35
src/api/anime/news.rs Normal file
View File

@ -0,0 +1,35 @@
use std::borrow::Cow;
use http::Method;
use crate::api::{
endpoint::Endpoint,
page::Pageable,
};
/// Retrieves a list of news articles related to the entry.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct News {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl News {
/// Create a builder for this endpoint.
pub fn builder() -> NewsBuilder {
NewsBuilder::default()
}
}
impl Endpoint for News {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/news", self.id).into()
}
}
impl Pageable for News {}

30
src/api/anime/pictures.rs Normal file
View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves pictures related to the entry.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Pictures {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Pictures {
/// Create a builder for this endpoint.
pub fn builder() -> PicturesBuilder {
PicturesBuilder::default()
}
}
impl Endpoint for Pictures {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/pictures", self.id).into()
}
}

View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime recommendations.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Recommendations {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Recommendations {
/// Create a builder for this endpoint.
pub fn builder() -> RecommendationsBuilder {
RecommendationsBuilder::default()
}
}
impl Endpoint for Recommendations {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/recommendations", self.id).into()
}
}

View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime relations.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Relations {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Relations {
/// Create a builder for this endpoint.
pub fn builder() -> RelationsBuilder {
RelationsBuilder::default()
}
}
impl Endpoint for Relations {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/relations", self.id).into()
}
}

49
src/api/anime/reviews.rs Normal file
View File

@ -0,0 +1,49 @@
use std::borrow::Cow;
use http::Method;
use serde::Serialize;
use crate::api::{
endpoint::Endpoint,
error::BodyError,
page::Pageable,
query_params::QueryParams,
};
/// Retrieves anime reviews.
#[derive(Debug, Clone, Builder, Serialize)]
#[builder(setter(into))]
pub struct Reviews {
#[doc = r"`ID` of the anime"]
#[serde(skip)]
id: u32,
#[doc = r"Any reviews left during an ongoing anime"]
#[builder(default, setter(strip_option))]
preliminary: Option<bool>,
#[doc = r"Any reviews that are tagged as a spoiler"]
#[builder(default, setter(strip_option))]
spoilers: Option<bool>,
}
impl Reviews {
/// Create a builder for this endpoint.
pub fn builder() -> ReviewsBuilder {
ReviewsBuilder::default()
}
}
impl Endpoint for Reviews {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/reviews", self.id).into()
}
fn query_params(&self) -> Result<QueryParams<'_>, BodyError> {
QueryParams::with(self)
}
}
impl Pageable for Reviews {}

148
src/api/anime/search.rs Normal file
View File

@ -0,0 +1,148 @@
use std::borrow::Cow;
use http::Method;
use serde::Serialize;
use crate::api::{
endpoint::Endpoint,
error::BodyError,
page::Pageable,
query_params::QueryParams,
};
/// Enum for the 'type' query parameter.
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum AnimeType {
Tv,
Movie,
Ova,
Special,
Ona,
Music,
Cm,
Pv,
TvSpecial,
}
/// Enum for the 'status' query parameter.
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum AnimeStatus {
Airing,
Complete,
Upcoming,
}
/// Enum for the 'rating' query parameter.
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum AnimeRating {
G,
PG,
PG13,
R17,
R,
Rx,
}
/// Enum for the 'order_by' query parameter.
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum AnimeOrderBy {
MalId,
Title,
StartDate,
EndDate,
Episodes,
Score,
ScoredBy,
Rank,
Popularity,
Members,
Favorites,
}
/// Enum for the 'sort' query parameter.
#[allow(missing_docs)]
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum AnimeSorting {
Asc,
Desc,
}
/// Search and retrieve anime resource data.
#[derive(Debug, Clone, Builder, Serialize)]
#[builder(setter(into))]
pub struct AnimeSearch<'a> {
// unapproved: bool,
/// The number of maximum results to return.
limit: u32,
/// Query string.
#[serde(rename = "q")]
query: Option<Cow<'a, str>>,
/// The type of anime to search.
#[serde(rename = "type")]
query_type: Option<AnimeType>,
/// Score of anime to search.
score: Option<f32>,
/// The minimum score to search.
min_score: Option<f32>,
/// The maximum score to search.
max_score: Option<f32>,
/// Status of anime to search.
status: Option<AnimeStatus>,
/// Audience rating of anime.
rating: Option<AnimeRating>,
/// Filter adult entries.
sfw: Option<bool>,
// TODO: custom type instead of ids
#[doc = r"Filter by genre(s) `ID`s. Can pass multiple with a comma as a delimiter"]
genres: Option<Cow<'a, str>>,
// TODO: custom type instead of ids
#[doc = r"Filter by genre(s) `ID`s. Can pass multiple with a comma as a delimiter"]
genres_exclude: Option<Cow<'a, str>>,
/// Sorting result by this parameter.
order_by: Option<AnimeOrderBy>,
/// Sorting order.
sorting: Option<AnimeSorting>,
/// Search entries starting with the given letter.
letter: Option<Cow<'a, str>>,
// TODO: custom type instead of ids
#[doc = r"Filter by producer(s) `ID`s. Can pass multiple with a comma as a delimiter"]
producers: Option<Cow<'a, str>>,
// TODO: custom date serializer
#[doc = r"Filter by starting date. Format: `YYYY-MM-DD`."]
start_date: Option<Cow<'a, str>>,
// TODO: custom date serializer
#[doc = r"Filter by ending date. Format: `YYYY-MM-DD`."]
end_date: Option<Cow<'a, str>>,
}
impl<'a> AnimeSearch<'a> {
/// Create a builder for this endpoint.
pub fn builder() -> AnimeSearchBuilder<'a> {
AnimeSearchBuilder::default()
}
}
impl Endpoint for AnimeSearch<'_> {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
"/anime".into()
}
fn query_params(&self) -> Result<QueryParams<'_>, BodyError> {
QueryParams::with(self)
}
}
impl Pageable for AnimeSearch<'_> {}

30
src/api/anime/staff.rs Normal file
View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime staff resource.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Staff {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Staff {
/// Create a builder for this endpoint.
pub fn builder() -> StaffBuilder {
StaffBuilder::default()
}
}
impl Endpoint for Staff {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/staff", self.id).into()
}
}

View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime statistics.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Statistics {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Statistics {
/// Create a builder for this endpoint.
pub fn builder() -> StatisticsBuilder {
StatisticsBuilder::default()
}
}
impl Endpoint for Statistics {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/statistics", self.id).into()
}
}

View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime streaming links.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Streaming {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Streaming {
/// Create a builder for this endpoint.
pub fn builder() -> StreamingBuilder {
StreamingBuilder::default()
}
}
impl Endpoint for Streaming {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/streaming", self.id).into()
}
}

30
src/api/anime/themes.rs Normal file
View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves anime themes.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Themes {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Themes {
/// Create a builder for this endpoint.
pub fn builder() -> ThemesBuilder {
ThemesBuilder::default()
}
}
impl Endpoint for Themes {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/themes", self.id).into()
}
}

View File

@ -0,0 +1,36 @@
use std::borrow::Cow;
use http::Method;
use crate::api::{
endpoint::Endpoint,
page::Pageable,
};
/// Retrieves a list of users who have added/updated/removed
/// the entry on their list.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct UserUpdates {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl UserUpdates {
/// Create a builder for this endpoint.
pub fn builder() -> UserUpdatesBuilder {
UserUpdatesBuilder::default()
}
}
impl Endpoint for UserUpdates {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/userupdates", self.id).into()
}
}
impl Pageable for UserUpdates {}

30
src/api/anime/videos.rs Normal file
View File

@ -0,0 +1,30 @@
use std::borrow::Cow;
use http::Method;
use crate::api::endpoint::Endpoint;
/// Retrieves videos related to the entry.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct Videos {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl Videos {
/// Create a builder for this endpoint.
pub fn builder() -> VideosBuilder {
VideosBuilder::default()
}
}
impl Endpoint for Videos {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/videos", self.id).into()
}
}

View File

@ -0,0 +1,35 @@
use std::borrow::Cow;
use http::Method;
use crate::api::{
endpoint::Endpoint,
page::Pageable,
};
/// Retrieves episode videos related to the entry.
#[derive(Debug, Clone, Builder)]
#[builder(setter(into))]
pub struct VideosEpisodes {
#[doc = r"`ID` of the anime"]
id: u32,
}
impl VideosEpisodes {
/// Create a builder for this endpoint.
pub fn builder() -> VideosEpisodesBuilder {
VideosEpisodesBuilder::default()
}
}
impl Endpoint for VideosEpisodes {
fn method(&self) -> http::Method {
Method::GET
}
fn endpoint(&self) -> Cow<'static, str> {
format!("/anime/{}/videos/episodes", self.id).into()
}
}
impl Pageable for VideosEpisodes {}