1use super::http::{PreStep, Request};
4use super::rule::Rule;
5use serde::{Deserialize, Serialize};
6use std::collections::BTreeMap;
7
8#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase", deny_unknown_fields)]
11#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
12pub struct BookRules {
13 #[serde(default, skip_serializing_if = "Option::is_none")]
15 pub book_url: Option<Rule>,
16 #[serde(default, skip_serializing_if = "Option::is_none")]
17 pub name: Option<Rule>,
18 #[serde(default, skip_serializing_if = "Option::is_none")]
19 pub author: Option<Rule>,
20 #[serde(default, skip_serializing_if = "Option::is_none")]
21 pub cover: Option<Rule>,
22 #[serde(default, skip_serializing_if = "Option::is_none")]
23 pub intro: Option<Rule>,
24 #[serde(default, skip_serializing_if = "Option::is_none")]
25 pub kind: Option<Rule>,
26 #[serde(default, skip_serializing_if = "Option::is_none")]
27 pub last_chapter: Option<Rule>,
28 #[serde(default, skip_serializing_if = "Option::is_none")]
29 pub toc_url: Option<Rule>,
30 #[serde(default, skip_serializing_if = "Option::is_none")]
31 pub word_count: Option<Rule>,
32}
33
34#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
38#[serde(rename_all = "camelCase", deny_unknown_fields)]
39#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
40pub struct BookInfoOp {
41 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub book_url: Option<Rule>,
43 #[serde(default, skip_serializing_if = "Option::is_none")]
44 pub name: Option<Rule>,
45 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub author: Option<Rule>,
47 #[serde(default, skip_serializing_if = "Option::is_none")]
48 pub cover: Option<Rule>,
49 #[serde(default, skip_serializing_if = "Option::is_none")]
50 pub intro: Option<Rule>,
51 #[serde(default, skip_serializing_if = "Option::is_none")]
52 pub kind: Option<Rule>,
53 #[serde(default, skip_serializing_if = "Option::is_none")]
54 pub last_chapter: Option<Rule>,
55 #[serde(default, skip_serializing_if = "Option::is_none")]
56 pub toc_url: Option<Rule>,
57 #[serde(default, skip_serializing_if = "Option::is_none")]
58 pub word_count: Option<Rule>,
59 #[serde(default, skip_serializing_if = "Vec::is_empty")]
61 pub prelude: Vec<PreStep>,
62}
63
64impl BookInfoOp {
65 pub fn as_book_rules(&self) -> BookRules {
67 BookRules {
68 book_url: self.book_url.clone(),
69 name: self.name.clone(),
70 author: self.author.clone(),
71 cover: self.cover.clone(),
72 intro: self.intro.clone(),
73 kind: self.kind.clone(),
74 last_chapter: self.last_chapter.clone(),
75 toc_url: self.toc_url.clone(),
76 word_count: self.word_count.clone(),
77 }
78 }
79}
80
81#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
88#[serde(rename_all = "camelCase", deny_unknown_fields)]
89#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
90pub struct ListPageSpec {
91 #[serde(default, skip_serializing_if = "Vec::is_empty")]
93 pub prelude: Vec<PreStep>,
94 pub request: Request,
95 pub list: Rule,
96 pub item: BookRules,
97}
98
99pub type SearchOp = ListPageSpec;
101
102#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
104#[serde(rename_all = "camelCase", deny_unknown_fields)]
105#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
106pub struct StaticEntry {
107 pub title: String,
108 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
110 pub vars: BTreeMap<String, String>,
111}
112
113#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
116#[serde(rename_all = "camelCase", deny_unknown_fields)]
117#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
118pub struct FetchEntryItem {
119 pub title: Rule,
120 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
121 pub vars: BTreeMap<String, Rule>,
122}
123
124#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
127#[serde(rename_all = "camelCase", deny_unknown_fields)]
128#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
129pub struct FetchEntrySource {
130 #[serde(default, skip_serializing_if = "Vec::is_empty")]
132 pub for_each: Vec<BTreeMap<String, String>>,
133 pub request: Request,
135 pub list: Rule,
137 pub item: FetchEntryItem,
138}
139
140#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
144#[serde(untagged)]
145#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
146pub enum EntrySource {
147 Static {
149 #[serde(rename = "static")]
150 static_entries: Vec<StaticEntry>,
151 },
152 Fetch { fetch: Box<FetchEntrySource> },
155}
156
157#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
159#[serde(rename_all = "camelCase", deny_unknown_fields)]
160#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
161pub struct ExploreOp {
162 pub entries: Vec<EntrySource>,
164 pub page: ListPageSpec,
166}
167
168fn default_max_pages() -> u32 {
169 100
170}
171
172#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
174#[serde(rename_all = "camelCase", deny_unknown_fields)]
175#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
176pub struct TocRules {
177 #[serde(default, skip_serializing_if = "Vec::is_empty")]
179 pub prelude: Vec<PreStep>,
180 pub list: Rule,
181 pub name: Rule,
182 pub url: Rule,
183 #[serde(default, skip_serializing_if = "Option::is_none")]
184 pub is_volume: Option<Rule>,
185 #[serde(default, skip_serializing_if = "Option::is_none")]
186 pub next_page: Option<Rule>,
187 #[serde(default = "default_max_pages")]
188 pub max_pages: u32,
189}
190
191#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
193#[serde(rename_all = "camelCase", deny_unknown_fields)]
194#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
195pub struct ContentRules {
196 #[serde(default, skip_serializing_if = "Vec::is_empty")]
198 pub prelude: Vec<PreStep>,
199 pub value: Rule,
200 #[serde(default, skip_serializing_if = "Option::is_none")]
201 pub next_page: Option<Rule>,
202 #[serde(default = "default_max_pages")]
203 pub max_pages: u32,
204}
205
206#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
208#[serde(rename_all = "camelCase")]
209#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
210pub struct Expect {
211 #[serde(default, skip_serializing_if = "Option::is_none")]
212 pub name: Option<String>,
213 #[serde(default, skip_serializing_if = "Option::is_none")]
214 pub min_chapters: Option<usize>,
215 #[serde(default, skip_serializing_if = "Option::is_none")]
216 pub volumes: Option<usize>,
217 #[serde(default, skip_serializing_if = "Option::is_none")]
218 pub min_content_chars: Option<usize>,
219}
220
221#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
223#[serde(rename_all = "camelCase", deny_unknown_fields)]
224#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
225pub struct Sample {
226 pub book_url: String,
227 #[serde(default)]
228 pub expect: Expect,
229}