mal_api/
common.rs

1//! Module containing common request/response fields, traits, and functions
2
3use std::{
4    collections::HashMap,
5    error::Error,
6    fmt::{self, Display},
7};
8
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug)]
12pub struct CommonError {
13    pub message: String,
14}
15
16impl Error for CommonError {}
17
18impl fmt::Display for CommonError {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        write!(f, "{}", self.message)
21    }
22}
23
24impl CommonError {
25    pub fn new(message: String) -> Self {
26        Self { message }
27    }
28}
29
30#[derive(Debug, Deserialize, Serialize)]
31pub struct Paging {
32    pub previous: Option<String>,
33    pub next: Option<String>,
34}
35
36impl Display for Paging {
37    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
39    }
40}
41
42#[derive(Debug, Deserialize, Serialize)]
43pub struct MainPicture {
44    pub medium: String,
45    pub large: String,
46}
47
48impl Display for MainPicture {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
51    }
52}
53
54#[derive(Debug, Deserialize, Serialize)]
55pub struct AlternativeTitles {
56    pub synonyms: Option<Vec<String>>,
57    pub en: Option<String>,
58    pub ja: Option<String>,
59}
60
61impl Display for AlternativeTitles {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
64    }
65}
66
67#[derive(Debug, Deserialize, Serialize, PartialEq)]
68pub enum NSFW {
69    #[serde(rename = "white")]
70    SFW,
71    #[serde(rename = "gray")]
72    MNSFW,
73    #[serde(rename = "black")]
74    NSFW,
75}
76
77#[derive(Debug, Deserialize, Serialize, PartialEq)]
78pub struct Genre {
79    pub id: u32,
80    pub name: String,
81}
82
83impl Display for Genre {
84    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
86    }
87}
88
89#[derive(Debug, Deserialize, Serialize)]
90pub struct Ranking {
91    pub rank: u32,
92    pub previous_rank: Option<u32>,
93}
94
95impl Display for Ranking {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        write!(f, "{}", serde_json::to_string(&self).unwrap_or_default())
98    }
99}
100
101#[derive(Debug, Deserialize, Serialize, PartialEq)]
102#[serde(rename_all = "snake_case")]
103pub enum RelationType {
104    Sequel,
105    Prequel,
106    AlternativeSetting,
107    AlternativeVersion,
108    SideStory,
109    ParentStory,
110    Summary,
111    FullStory,
112    Character, // this type is not documented in the MAL API reference...
113}
114
115pub(crate) fn struct_to_form_data<T>(query: &T) -> Result<HashMap<String, String>, Box<dyn Error>>
116where
117    T: Serialize,
118{
119    let form = serde_urlencoded::to_string(&query)?
120        .split('&')
121        .map(|x| {
122            let mut parts = x.splitn(2, "=");
123            let key = parts.next().unwrap().to_string();
124            let value = parts.next().unwrap_or("").to_string();
125            (key, value)
126        })
127        .collect();
128    Ok(form)
129}
130
131pub trait PagingIter {
132    type Item;
133
134    fn next_page(&self) -> Option<&String>;
135
136    fn prev_page(&self) -> Option<&String>;
137}