1use super::alloc::{String, Vec};
4use serde::{Deserialize, Serialize};
5
6pub use hashbrown::HashMap;
7
8pub mod canvas;
9mod filter;
10mod home;
11mod setting;
12
13pub use filter::*;
14pub use home::*;
15pub use setting::*;
16
17#[cfg(feature = "imports")]
18mod source;
19
20#[cfg(feature = "imports")]
21pub use source::*;
22
23pub type PageContext = HashMap<String, String>;
25
26#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
28pub enum MangaStatus {
29 #[default]
30 Unknown = 0,
31 Ongoing,
32 Completed,
33 Cancelled,
34 Hiatus,
35}
36
37#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
39pub enum ContentRating {
40 #[default]
41 Unknown = 0,
42 Safe,
43 Suggestive,
44 NSFW,
45}
46
47#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
53pub enum Viewer {
54 #[default]
55 Unknown = 0,
56 LeftToRight,
57 RightToLeft,
58 Vertical,
59 Webtoon,
60}
61
62#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
68pub enum UpdateStrategy {
69 #[default]
70 Always,
71 Never,
72}
73
74#[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)]
76pub struct Manga {
77 pub key: String,
79 pub title: String,
81 pub cover: Option<String>,
83 pub artists: Option<Vec<String>>,
85 pub authors: Option<Vec<String>>,
87 pub description: Option<String>,
89 pub url: Option<String>,
91 pub tags: Option<Vec<String>>,
93 pub status: MangaStatus,
95 pub content_rating: ContentRating,
97 pub viewer: Viewer,
99 pub update_strategy: UpdateStrategy,
101 pub next_update_time: Option<i64>,
103 pub chapters: Option<Vec<Chapter>>,
105}
106
107impl Manga {
108 pub fn copy_from(&mut self, manga: Manga) {
110 self.key = manga.key;
111 self.title = manga.title;
112 if let Some(cover) = manga.cover {
113 self.cover = Some(cover);
114 }
115 if let Some(artists) = manga.artists {
116 self.artists = Some(artists);
117 }
118 if let Some(authors) = manga.authors {
119 self.authors = Some(authors);
120 }
121 if let Some(description) = manga.description {
122 self.description = Some(description);
123 }
124 if let Some(url) = manga.url {
125 self.url = Some(url);
126 }
127 if let Some(tags) = manga.tags {
128 self.tags = Some(tags);
129 }
130 self.status = manga.status;
131 self.content_rating = manga.content_rating;
132 self.viewer = manga.viewer;
133 self.update_strategy = manga.update_strategy;
134 if let Some(next_update_time) = manga.next_update_time {
135 self.next_update_time = Some(next_update_time);
136 }
137 if let Some(chapters) = manga.chapters {
138 self.chapters = Some(chapters);
139 }
140 }
141}
142
143#[derive(Default, Clone, Debug, PartialEq, Serialize)]
145pub struct MangaPageResult {
146 pub entries: Vec<Manga>,
148 pub has_next_page: bool,
150}
151
152#[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)]
154pub struct Chapter {
155 pub key: String,
157 pub title: Option<String>,
159 pub chapter_number: Option<f32>,
161 pub volume_number: Option<f32>,
163 pub date_uploaded: Option<i64>,
165 pub scanlators: Option<Vec<String>>,
167 pub url: Option<String>,
169 pub language: Option<String>,
171 pub thumbnail: Option<String>,
173 pub locked: bool,
175}
176
177#[cfg(feature = "imports")]
178mod __private {
179 use crate::imports::canvas::ImageRef;
180
181 #[derive(Debug, PartialEq)]
182 pub struct ImageRefPriv(pub(crate) ImageRef);
183
184 impl serde::Serialize for ImageRefPriv {
185 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
186 where
187 S: serde::Serializer,
188 {
189 self.0.serialize(serializer)
190 }
191 }
192
193 impl<'de> serde::Deserialize<'de> for ImageRefPriv {
194 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
195 where
196 D: serde::Deserializer<'de>,
197 {
198 ImageRef::deserialize(deserializer).map(ImageRefPriv)
199 }
200 }
201}
202
203#[derive(Debug, PartialEq, Serialize, Deserialize)]
205pub enum PageContent {
206 Url(String, Option<PageContext>),
211 Text(String),
213 #[cfg(feature = "imports")]
215 Image(__private::ImageRefPriv),
216 Zip(String, String),
218}
219
220impl PageContent {
221 pub fn url<T: Into<String>>(url: T) -> Self {
223 Self::Url(url.into(), None)
224 }
225
226 pub fn url_context<T: Into<String>>(url: T, context: PageContext) -> Self {
228 Self::Url(url.into(), Some(context))
229 }
230
231 pub fn text<T: Into<String>>(text: T) -> Self {
233 Self::Text(text.into())
234 }
235
236 #[cfg(feature = "imports")]
238 pub fn image(image: crate::imports::canvas::ImageRef) -> Self {
239 Self::Image(__private::ImageRefPriv(image))
240 }
241}
242
243#[derive(Debug, PartialEq, Serialize, Deserialize)]
245pub struct Page {
246 pub content: PageContent,
248 pub thumbnail: Option<String>,
250 pub has_description: bool,
252 pub description: Option<String>,
257}
258
259impl Page {
260 #[cfg(feature = "imports")]
265 pub fn ensure_externally_managed(&mut self) {
266 if let PageContent::Image(ref mut image) = self.content {
267 image.0.externally_managed = true;
268 }
269 }
270}
271
272impl Default for Page {
273 fn default() -> Self {
274 Self {
275 content: PageContent::Text(String::default()),
276 thumbnail: None,
277 has_description: false,
278 description: None,
279 }
280 }
281}
282
283#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
285pub enum ListingKind {
286 #[default]
287 Default,
288 List,
289}
290
291#[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)]
293pub struct Listing {
294 pub id: String,
296 pub name: String,
298 pub kind: ListingKind,
300}