mangadex_api_schema_rust/v5/
manga_links.rs1use serde::{Deserialize, Serialize};
2use url::Url;
3
4#[derive(Clone, Debug, Default, Deserialize, Hash, PartialEq, Serialize)]
6#[serde(rename_all = "snake_case")]
7#[cfg_attr(feature = "non_exhaustive", non_exhaustive)]
8#[cfg_attr(feature = "specta", derive(specta::Type))]
9pub struct MangaLinks {
10 #[serde(rename = "amz")]
18 #[cfg_attr(feature = "specta", specta(type = Option<String>))]
19 #[serde(skip_serializing_if = "Option::is_none")]
20 pub amazon: Option<Url>,
21
22 #[serde(rename = "al")]
30 #[serde(skip_serializing_if = "Option::is_none")]
31 pub anilist: Option<String>,
32
33 #[serde(rename = "ap")]
42 #[serde(skip_serializing_if = "Option::is_none")]
43 pub anime_planet: Option<String>,
44
45 #[serde(rename = "bw")]
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub book_walker: Option<BookWalker>,
57 #[serde(rename = "cdj")]
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub cd_japan: Option<String>,
68
69 #[serde(rename = "ebj")]
78 #[serde(skip_serializing_if = "Option::is_none")]
79 #[cfg_attr(feature = "specta", specta(type = Option<String>))]
80 pub ebook_japan: Option<Url>,
81
82 #[serde(rename = "engtl")]
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub english_translation: Option<String>,
92
93 #[serde(rename = "kt")]
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub kitsu: Option<String>,
108
109 #[serde(rename = "mu")]
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub manga_updates: Option<MangaUpdates>,
119
120 #[serde(rename = "mal")]
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub my_anime_list: Option<MyAnimeList>,
130
131 #[serde(rename = "nu")]
139 #[serde(skip_serializing_if = "Option::is_none")]
140 pub novel_updates: Option<NovelUpdates>,
141
142 #[cfg_attr(feature = "specta", specta(type = Option<String>))]
151 #[serde(skip_serializing_if = "Option::is_none")]
152 pub raw: Option<Url>,
153}
154
155impl MangaLinks {
156 pub(crate) fn has_no_links(&self) -> bool {
160 self.amazon.is_none()
161 && self.anilist.is_none()
162 && self.anime_planet.is_none()
163 && self.book_walker.is_none()
164 && self.cd_japan.is_none()
165 && self.ebook_japan.is_none()
166 && self.english_translation.is_none()
167 && self.kitsu.is_none()
168 && self.manga_updates.is_none()
169 && self.my_anime_list.is_none()
170 && self.novel_updates.is_none()
171 && self.raw.is_none()
172 }
173}
174
175#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)]
179#[cfg_attr(feature = "specta", derive(specta::Type))]
180pub struct BookWalker(pub String);
181
182impl std::fmt::Display for BookWalker {
183 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
184 fmt.write_str(&format!("https://bookwalker.jp/{}", self.0))
185 }
186}
187
188#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)]
192#[cfg_attr(feature = "specta", derive(specta::Type))]
193pub struct MangaUpdates(pub String);
194
195impl std::fmt::Display for MangaUpdates {
196 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
197 fmt.write_str(&format!(
198 "https://www.mangaupdates.com/series.html?id={}",
199 self.0
200 ))
201 }
202}
203
204#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)]
208#[cfg_attr(feature = "specta", derive(specta::Type))]
209pub struct MyAnimeList(pub String);
210
211impl std::fmt::Display for MyAnimeList {
212 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
213 fmt.write_str(&format!("https://myanimelist.net/manga/{}", self.0))
214 }
215}
216
217#[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)]
221#[cfg_attr(feature = "specta", derive(specta::Type))]
222pub struct NovelUpdates(pub String);
223
224impl std::fmt::Display for NovelUpdates {
225 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
226 fmt.write_str(&format!("https://www.novelupdates.com/series/{}/", self.0))
227 }
228}