1use super::rule::{Rule, UrlOrRule};
4use serde::{Deserialize, Serialize};
5use std::collections::{BTreeMap, HashMap};
6
7#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "kebab-case")]
10#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
11pub enum Charset {
12 #[default]
13 Auto,
14 Utf8,
15 Gbk,
16 Gb18030,
17 Big5,
18}
19
20#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
22#[serde(rename_all = "camelCase", deny_unknown_fields)]
23#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
24pub struct Retry {
25 #[serde(default)]
26 pub max: u32,
27 #[serde(default)]
28 pub backoff_ms: u64,
29}
30
31#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
33#[serde(rename_all = "camelCase", deny_unknown_fields)]
34#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
35pub struct RateLimit {
36 pub max_count: u64,
37 pub per_ms: u64,
38}
39
40#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
45#[serde(rename_all = "camelCase", deny_unknown_fields)]
46#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
47pub struct PageBy {
48 pub click: String,
50}
51
52#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
55#[serde(rename_all = "lowercase")]
56#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
57pub enum FetchMode {
58 #[default]
60 Auto,
61 Reqwest,
63 Browser,
65}
66
67#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
69#[serde(rename_all = "camelCase", deny_unknown_fields)]
70#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
71pub struct Http {
72 #[serde(default)]
73 pub headers: HashMap<String, String>,
74 #[serde(default)]
76 pub cookies: HashMap<String, String>,
77 #[serde(default)]
79 pub warmup: Vec<String>,
80 #[serde(default)]
81 pub charset: Charset,
82 #[serde(default, skip_serializing_if = "Option::is_none")]
83 pub timeout: Option<u64>,
84 #[serde(default, skip_serializing_if = "Option::is_none")]
85 pub retry: Option<Retry>,
86 #[serde(default, skip_serializing_if = "Option::is_none")]
87 pub rate_limit: Option<RateLimit>,
88 #[serde(default)]
90 pub fetcher: FetchMode,
91}
92
93#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
95#[serde(rename_all = "lowercase")]
96#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
97pub enum RowUiType {
98 #[default]
100 Text,
101 Password,
103 Select,
105 Toggle,
107}
108
109#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
111#[serde(rename_all = "camelCase", deny_unknown_fields)]
112#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
113pub struct RowUi {
114 pub name: String,
116 #[serde(rename = "type", default)]
117 pub ui_type: RowUiType,
118 #[serde(default, skip_serializing_if = "Vec::is_empty")]
120 pub options: Vec<String>,
121}
122
123#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
125#[serde(rename_all = "UPPERCASE")]
126#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
127pub enum Method {
128 #[default]
129 Get,
130 Post,
131}
132
133#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Hash)]
136#[serde(rename_all = "lowercase")]
137#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
138pub enum VarScope {
139 #[default]
142 Chapter,
143 Book,
147 Source,
150}
151
152#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
155#[serde(rename_all = "camelCase", deny_unknown_fields)]
156#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
157pub struct Capture {
158 pub name: String,
160 pub value: Rule,
162 #[serde(default)]
164 pub scope: VarScope,
165}
166
167#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
171#[serde(rename_all = "camelCase", deny_unknown_fields)]
172#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
173pub struct PreStep {
174 pub url: UrlOrRule,
175 #[serde(default)]
176 pub method: Method,
177 #[serde(default, skip_serializing_if = "Option::is_none")]
178 pub body: Option<UrlOrRule>,
179 #[serde(default)]
181 pub headers: HashMap<String, String>,
182 #[serde(default, skip_serializing_if = "Vec::is_empty")]
184 pub capture: Vec<Capture>,
185 #[serde(default, skip_serializing_if = "Vec::is_empty")]
187 pub skip_if_present: Vec<String>,
188}
189
190#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
192#[serde(rename_all = "camelCase", deny_unknown_fields)]
193#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
194pub struct Request {
195 pub url: UrlOrRule,
196 #[serde(default)]
197 pub method: Method,
198 #[serde(default, skip_serializing_if = "Option::is_none")]
199 pub body: Option<UrlOrRule>,
200 #[serde(default)]
201 pub headers: HashMap<String, String>,
202 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
207 pub vars: BTreeMap<String, Rule>,
208 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
212 pub render: bool,
213 #[serde(default, skip_serializing_if = "Option::is_none")]
218 pub ready_for: Option<String>,
219 #[serde(default, skip_serializing_if = "Option::is_none")]
223 pub intercept_api: Option<String>,
224 #[serde(default, skip_serializing_if = "Option::is_none")]
228 pub total_pages: Option<Rule>,
229 #[serde(default, skip_serializing_if = "Option::is_none")]
232 pub has_more: Option<Rule>,
233 #[serde(default, skip_serializing_if = "Option::is_none")]
238 pub page_by: Option<PageBy>,
239}