anidb_api/http/models/anime/
episode.rs

1use crate::http::models::common::{ApiError, Title};
2use serde::{Deserialize, Serialize};
3use std::str::FromStr;
4
5#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
6#[serde(from = "FromEpisode")]
7// #[serde(into = "FromEpisode")]
8pub struct Episode {
9    pub episode_id: String,
10    pub episode_num: Option<String>,
11    pub episode_type: Option<EpisodeType>,
12    pub length: Option<String>,
13    pub updated: Option<String>,
14    pub titles: Vec<Title>,
15    pub description: Option<String>,
16    pub air_date: Option<String>, // date
17}
18
19#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
20pub enum EpisodeType {
21    #[serde(rename(deserialize = "1"))]
22    Episode = 1,
23    #[serde(rename(deserialize = "2"))]
24    Credits = 2,
25    #[serde(rename(deserialize = "3"))]
26    Special = 3,
27    #[serde(rename(deserialize = "4"))]
28    Trailer = 4,
29    #[serde(rename(deserialize = "5"))]
30    Parody = 5,
31    #[serde(rename(deserialize = "6"))]
32    Other = 6,
33}
34
35#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
36pub(crate) struct EpisodeList {
37    #[serde(rename = "episode")]
38    pub list: Vec<Episode>,
39}
40
41#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
42pub(crate) struct FromEpisode {
43    #[serde(rename = "id")]
44    pub episode_id: String,
45    pub epno: Option<EpisodeNumber>,
46    pub length: Option<String>,
47    #[serde(rename = "update")]
48    pub updated: Option<String>,
49    #[serde(rename = "title")]
50    pub titles: Option<Vec<Title>>,
51    pub description: Option<String>,
52    #[serde(rename = "airdate")]
53    pub air_date: Option<String>, // date
54}
55
56#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
57pub(crate) struct EpisodeNumber {
58    #[serde(rename(deserialize = "$value"))]
59    pub episode_num: Option<String>,
60    #[serde(rename = "type")]
61    pub episode_type: Option<String>,
62}
63
64impl From<FromEpisode> for Episode {
65    fn from(value: FromEpisode) -> Self {
66        let (episode_num, episode_type) = value
67            .epno
68            .map_or_else(|| (None, None), |x| (x.episode_num, x.episode_type));
69        Self {
70            episode_id: value.episode_id,
71            episode_num,
72            episode_type: episode_type.map(|x| EpisodeType::from_str(&x).unwrap()),
73            length: value.length,
74            updated: value.updated,
75            titles: value.titles.unwrap_or_default(),
76            description: value.description,
77            air_date: value.air_date,
78        }
79    }
80}
81
82impl From<Episode> for FromEpisode {
83    fn from(value: Episode) -> Self {
84        let epno = if value.episode_num.is_none() && value.episode_type.is_none() {
85            None
86        } else {
87            Some(EpisodeNumber {
88                episode_num: value.episode_num,
89                episode_type: value.episode_type.map(|x| x.to_string()),
90            })
91        };
92
93        Self {
94            episode_id: value.episode_id,
95            epno,
96            length: value.length,
97            updated: value.updated,
98            titles: if value.titles.is_empty() {
99                None
100            } else {
101                Some(value.titles)
102            },
103            description: value.description,
104            air_date: value.air_date,
105        }
106    }
107}
108
109impl FromStr for EpisodeType {
110    type Err = ApiError;
111
112    fn from_str(s: &str) -> Result<Self, Self::Err> {
113        match s {
114            "1" => Ok(EpisodeType::Episode),
115            "2" => Ok(EpisodeType::Credits),
116            "3" => Ok(EpisodeType::Special),
117            "4" => Ok(EpisodeType::Trailer),
118            "5" => Ok(EpisodeType::Parody),
119            "6" => Ok(EpisodeType::Other),
120            _ => Err(ApiError::Parse(
121                "Error parse &str to EpisodeType".to_string(),
122            )),
123        }
124    }
125}
126
127impl std::fmt::Display for EpisodeType {
128    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129        std::fmt::Debug::fmt(self, f)
130    }
131}