1use std::collections::HashMap;
5
6use serde::Serialize;
7use serde_json::Value;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
11#[serde(rename_all = "lowercase")]
12pub enum ParseMode {
13 Accurate,
15 Speed,
17}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
21#[serde(rename_all = "lowercase")]
22pub enum PageComplexity {
23 Low,
25 High,
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
31#[serde(rename_all = "lowercase")]
32pub enum DetailLevel {
33 Low,
35 Medium,
37 High,
39}
40
41#[derive(Debug, Clone, Default, Serialize)]
55pub struct ScrapeRequest {
56 pub website_url: String,
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub clean: Option<bool>,
61 #[serde(skip_serializing_if = "Option::is_none")]
63 pub parse_mode: Option<ParseMode>,
64 #[serde(skip_serializing_if = "Option::is_none")]
66 pub tag_truncate: Option<bool>,
67 #[serde(skip_serializing_if = "Option::is_none")]
69 pub extract_links: Option<bool>,
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub include_tags: Option<Vec<String>>,
73 #[serde(skip_serializing_if = "Option::is_none")]
75 pub exclude_tags: Option<Vec<String>>,
76 #[serde(skip_serializing_if = "Option::is_none")]
78 pub headers: Option<HashMap<String, String>>,
79 #[serde(skip_serializing_if = "Option::is_none")]
81 pub max_age: Option<u64>,
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub stealth: Option<bool>,
85}
86
87impl ScrapeRequest {
88 pub fn new(website_url: impl Into<String>) -> Self {
90 Self {
91 website_url: website_url.into(),
92 ..Default::default()
93 }
94 }
95
96 pub fn clean(mut self, clean: bool) -> Self {
98 self.clean = Some(clean);
99 self
100 }
101
102 pub fn parse_mode(mut self, mode: ParseMode) -> Self {
104 self.parse_mode = Some(mode);
105 self
106 }
107
108 pub fn tag_truncate(mut self, tag_truncate: bool) -> Self {
110 self.tag_truncate = Some(tag_truncate);
111 self
112 }
113
114 pub fn extract_links(mut self, extract_links: bool) -> Self {
116 self.extract_links = Some(extract_links);
117 self
118 }
119
120 pub fn include_tags<I, S>(mut self, tags: I) -> Self
122 where
123 I: IntoIterator<Item = S>,
124 S: Into<String>,
125 {
126 self.include_tags = Some(tags.into_iter().map(Into::into).collect());
127 self
128 }
129
130 pub fn exclude_tags<I, S>(mut self, tags: I) -> Self
132 where
133 I: IntoIterator<Item = S>,
134 S: Into<String>,
135 {
136 self.exclude_tags = Some(tags.into_iter().map(Into::into).collect());
137 self
138 }
139
140 pub fn header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
142 self.headers
143 .get_or_insert_with(HashMap::new)
144 .insert(key.into(), value.into());
145 self
146 }
147
148 pub fn headers(mut self, headers: HashMap<String, String>) -> Self {
150 self.headers = Some(headers);
151 self
152 }
153
154 pub fn max_age(mut self, seconds: u64) -> Self {
156 self.max_age = Some(seconds);
157 self
158 }
159
160 pub fn stealth(mut self, stealth: bool) -> Self {
162 self.stealth = Some(stealth);
163 self
164 }
165}
166
167#[derive(Debug, Clone, Default, Serialize)]
171pub struct SmartScraperRequest {
172 pub website_url: String,
174 pub user_prompt: String,
177 #[serde(skip_serializing_if = "Option::is_none")]
179 pub output_schema: Option<Value>,
180 #[serde(skip_serializing_if = "Option::is_none")]
182 pub page_complexity: Option<PageComplexity>,
183 #[serde(skip_serializing_if = "Option::is_none")]
185 pub detail_level: Option<DetailLevel>,
186 #[serde(skip_serializing_if = "Option::is_none")]
188 pub parse_mode: Option<ParseMode>,
189 #[serde(skip_serializing_if = "Option::is_none")]
191 pub plain_text: Option<bool>,
192 #[serde(skip_serializing_if = "Option::is_none")]
194 pub include_tags: Option<Vec<String>>,
195 #[serde(skip_serializing_if = "Option::is_none")]
197 pub exclude_tags: Option<Vec<String>>,
198 #[serde(skip_serializing_if = "Option::is_none")]
200 pub reduce_content: Option<bool>,
201 #[serde(skip_serializing_if = "Option::is_none")]
204 pub experimental: Option<bool>,
205 #[serde(skip_serializing_if = "Option::is_none")]
208 pub headers: Option<HashMap<String, String>>,
209 #[serde(skip_serializing_if = "Option::is_none")]
211 pub max_age: Option<u64>,
212 #[serde(skip_serializing_if = "Option::is_none")]
214 pub stealth: Option<bool>,
215}
216
217impl SmartScraperRequest {
218 pub fn new(website_url: impl Into<String>, user_prompt: impl Into<String>) -> Self {
220 Self {
221 website_url: website_url.into(),
222 user_prompt: user_prompt.into(),
223 ..Default::default()
224 }
225 }
226
227 pub fn output_schema(mut self, schema: Value) -> Self {
229 self.output_schema = Some(schema);
230 self
231 }
232
233 pub fn page_complexity(mut self, complexity: PageComplexity) -> Self {
235 self.page_complexity = Some(complexity);
236 self
237 }
238
239 pub fn detail_level(mut self, level: DetailLevel) -> Self {
241 self.detail_level = Some(level);
242 self
243 }
244
245 pub fn parse_mode(mut self, mode: ParseMode) -> Self {
247 self.parse_mode = Some(mode);
248 self
249 }
250
251 pub fn plain_text(mut self, plain_text: bool) -> Self {
253 self.plain_text = Some(plain_text);
254 self
255 }
256
257 pub fn include_tags<I, S>(mut self, tags: I) -> Self
259 where
260 I: IntoIterator<Item = S>,
261 S: Into<String>,
262 {
263 self.include_tags = Some(tags.into_iter().map(Into::into).collect());
264 self
265 }
266
267 pub fn exclude_tags<I, S>(mut self, tags: I) -> Self
269 where
270 I: IntoIterator<Item = S>,
271 S: Into<String>,
272 {
273 self.exclude_tags = Some(tags.into_iter().map(Into::into).collect());
274 self
275 }
276
277 pub fn reduce_content(mut self, reduce_content: bool) -> Self {
279 self.reduce_content = Some(reduce_content);
280 self
281 }
282
283 pub fn experimental(mut self, experimental: bool) -> Self {
286 self.experimental = Some(experimental);
287 self
288 }
289
290 pub fn header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
292 self.headers
293 .get_or_insert_with(HashMap::new)
294 .insert(key.into(), value.into());
295 self
296 }
297
298 pub fn headers(mut self, headers: HashMap<String, String>) -> Self {
300 self.headers = Some(headers);
301 self
302 }
303
304 pub fn max_age(mut self, seconds: u64) -> Self {
306 self.max_age = Some(seconds);
307 self
308 }
309
310 pub fn stealth(mut self, stealth: bool) -> Self {
312 self.stealth = Some(stealth);
313 self
314 }
315}