mal/api/
manga.rs

1use super::model::*;
2use super::Error;
3use super::{get, handle_response, API_URL};
4use crate::auth::OAuth;
5use serde::Serialize;
6
7#[derive(Clone, Debug, Serialize)]
8pub struct GetMangaListQuery {
9    pub q: String,
10    pub limit: u64,
11    pub offset: u64,
12    pub nsfw: bool,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub fields: Option<String>,
15}
16
17pub async fn get_manga_list(query: &GetMangaListQuery, auth: &OAuth) -> Result<Page<Manga>, Error> {
18    let response = get(
19        &format! {"{}/manga?{}", API_URL, serde_urlencoded::to_string(query)?},
20        auth,
21    )
22    .await?;
23    handle_response(&response)
24}
25
26#[derive(Clone, Debug, Serialize)]
27pub struct GetMangaDetailQuery {
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub fields: Option<String>,
30    pub nsfw: bool,
31}
32
33pub async fn get_manga_details(
34    manga_id: u64,
35    query: &GetMangaDetailQuery,
36    auth: &OAuth,
37) -> Result<Manga, Error> {
38    let response = get(
39        &format!(
40            "{}/manga/{}?{}",
41            API_URL,
42            manga_id,
43            serde_urlencoded::to_string(query)?
44        ),
45        auth,
46    )
47    .await?;
48    handle_response(&response)
49}
50
51#[derive(Clone, Debug, Serialize)]
52pub struct GetMangaRankingQuery {
53    pub ranking_type: MangaRankingType,
54    pub limit: u64,
55    pub offset: u64,
56    pub nsfw: bool,
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub fields: Option<String>,
59}
60
61pub async fn get_manga_ranking(
62    query: &GetMangaRankingQuery,
63    auth: &OAuth,
64) -> Result<Ranking<RankingMangaPair>, Error> {
65    let response = get(
66        &format!(
67            "{}/manga/ranking?{}",
68            API_URL,
69            serde_urlencoded::to_string(query)?
70        ),
71        auth,
72    )
73    .await?;
74    handle_response(&response)
75}
76
77#[cfg(test)]
78pub mod tests {
79    use super::*;
80
81    pub async fn get_manga<T: ToString>(q: T, auth: &OAuth) -> Result<Manga, Error> {
82        let manga_query = GetMangaListQuery {
83            q: q.to_string(),
84            limit: 4,
85            offset: 0,
86            nsfw: false,
87            fields: Some(ALL_ANIME_AND_MANGA_FIELDS.to_string()),
88        };
89        let manga_list = get_manga_list(&manga_query, auth).await.unwrap();
90        let manga = manga_list.data.first().unwrap().node.clone();
91        Ok(manga)
92    }
93
94    #[tokio::test]
95    async fn test_get_manga_list() {
96        let auth = crate::auth::tests::get_auth();
97        let query = GetMangaListQuery {
98            q: "Kaguya-Sama Wa Kokurasetai".to_string(),
99            limit: 2,
100            offset: 0,
101            nsfw: false,
102            fields: Some(ALL_ANIME_AND_MANGA_FIELDS.to_string()),
103        };
104        let result = get_manga_list(&query, &auth).await.unwrap();
105        println!("{:#?}", result);
106        assert!(!result.data.is_empty());
107    }
108
109    #[tokio::test]
110    async fn test_get_manga_details() {
111        let auth = crate::auth::tests::get_auth();
112        let query = GetMangaDetailQuery {
113            fields: Some(ALL_ANIME_AND_MANGA_FIELDS.to_string()),
114            nsfw: false,
115        };
116
117        let manga = get_manga("Kaguya-Sama Wa Kokurasetai", &auth)
118            .await
119            .unwrap();
120        let result = get_manga_details(manga.id, &query, &auth).await.unwrap();
121        println!("{:#?}", result);
122        assert_eq!(result.title, manga.title);
123    }
124
125    #[tokio::test]
126    async fn test_get_manga_ranking() {
127        let auth = crate::auth::tests::get_auth();
128        let query = GetMangaRankingQuery {
129            ranking_type: MangaRankingType::All,
130            limit: 100,
131            offset: 0,
132            nsfw: false,
133            fields: Some(ALL_ANIME_AND_MANGA_FIELDS.to_string()),
134        };
135        let result = get_manga_ranking(&query, &auth).await.unwrap();
136        println!("{:#?}", result);
137        assert!(!result.data.is_empty());
138    }
139}