1use core::fmt;
2
3use chrono::NaiveDate;
4use serde::Deserialize;
5use serde_json::Value;
6
7#[derive(Debug, Deserialize, Clone)]
8pub struct AnimeList {
9 id: i64,
10 title: String,
11 status: String,
12 finish_date: String,
13}
14
15impl AnimeList {
16 pub fn new(value: &Value) -> Self {
17 let (id, title) = Self::parse_node(value);
19 let (status, finish_date) = Self::parse_status(value);
20 Self {
21 id: id.unwrap(),
22 title: title.unwrap().to_string(),
23 status: status.unwrap().to_string(),
24 finish_date: finish_date.unwrap().to_string(),
25 }
26 }
28
29 fn parse_node(value: &Value) -> (Option<i64>, Option<&str>) {
30 let node = value.get("node");
31 match node {
32 Some(anime) => (
33 anime.get("id").unwrap().as_i64(),
34 anime.get("title").unwrap().as_str(),
35 ),
36 _ => (None, None),
37 }
38 }
39
40 fn parse_status(value: &Value) -> (Option<&str>, Option<&str>) {
41 let status = value.get("list_status");
42 match status {
43 Some(anime_status) => (
44 anime_status.get("status").unwrap().as_str(),
45 if let Some(date) = anime_status.get("finish_date") {
46 date.as_str()
47 } else {
48 Some("-")
49 },
50 ),
51 _ => (None, None),
52 }
53 }
54
55 pub fn get_title(self) -> String {
56 self.title
57 }
58
59 pub fn get_id(&self) -> i64 {
60 self.id
61 }
62
63 pub fn get_status(self) -> String {
64 self.status
65 }
66}
67
68impl fmt::Display for AnimeList {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 let mut finish_date = "-".to_string();
71 if self.finish_date != "-" {
72 finish_date = NaiveDate::parse_from_str(self.finish_date.as_str(), "%Y-%m-%d")
73 .unwrap()
74 .format("%b %d, %Y")
75 .to_string()
76 }
77
78 write!(f, "{}\t{:>9}\t{}", self.status, finish_date, self.title)
80 }
81}
82
83#[derive(Debug, Deserialize)]
84pub struct Anime {
85 id: i64,
86 title: String,
87 start_date: String,
88 end_date: Option<String>,
89 synopsis: String,
90 mean: f64,
91 rank: i64,
92}
93
94impl Anime {
95 pub fn get_id(self) -> i64 {
96 self.id
97 }
98
99 pub fn get_title(self) -> String {
100 self.title
101 }
102
103 pub fn get_synopsis(self) -> String {
104 self.synopsis
105 }
106
107 pub fn get_rank(self) -> i64 {
108 self.rank
109 }
110}
111
112impl fmt::Display for Anime {
113 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114 let mut start_date = "-".to_string();
115 if self.start_date != "-" {
116 start_date = NaiveDate::parse_from_str(self.start_date.as_str(), "%Y-%m-%d")
117 .unwrap()
118 .format("%b %d, %Y")
119 .to_string()
120 }
121
122 let end_date = match &self.end_date {
123 Some(date) => NaiveDate::parse_from_str(&date.as_str(), "%Y-%m-%d")
124 .unwrap()
125 .format("%b %d, %Y")
126 .to_string(),
127 _ => "-".to_string(),
128 };
129
130 write!(
132 f,
133 "Start\t{}\nEnd\t{}\nScore\t{}\n",
134 start_date, end_date, self.mean
135 )
136 }
137}
138
139#[derive(Debug, Deserialize, Clone)]
140pub struct SeasonalAnime {
141 id: i64,
142 title: String,
143}
144
145impl SeasonalAnime {
146 pub fn get_id(self) -> i64 {
147 self.id
148 }
149
150 pub fn get_title(self) -> String {
151 self.title
152 }
153}
154
155impl fmt::Display for SeasonalAnime {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 write!(f, "{}\t{}", self.id, self.title)
158 }
159}