1use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use std::collections::BTreeMap;
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9#[serde(rename_all = "camelCase")]
10pub struct CrawlSummary {
11 pub stop_reason: String,
14 #[serde(skip_serializing_if = "Option::is_none")]
16 pub coverage: Option<f64>,
17 #[serde(skip_serializing_if = "BTreeMap::is_empty", default)]
19 pub term_evidence: BTreeMap<String, usize>,
20 pub pages: usize,
22}
23
24#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
27#[serde(rename_all = "camelCase")]
28pub struct CrawlTrace {
29 pub depth: usize,
31 #[serde(skip_serializing_if = "Option::is_none")]
33 pub parent: Option<String>,
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub score: Option<f32>,
37 #[serde(skip_serializing_if = "Option::is_none")]
39 pub attachment_of: Option<String>,
40}
41
42#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
44#[serde(rename_all = "camelCase")]
45pub struct OcrMeta {
46 pub engine: String,
47 pub model: String,
48 pub device: String,
50 pub pages: usize,
52 pub fallback: bool,
54}
55
56#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
57#[serde(rename_all = "camelCase")]
58pub struct PagesiftMeta {
59 #[serde(skip_serializing_if = "Option::is_none")]
60 pub content_hash: Option<String>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub raw_hash: Option<String>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 pub text_hash: Option<String>,
65 #[serde(skip_serializing_if = "Vec::is_empty", default)]
66 pub redirect_chain: Vec<String>,
67 #[serde(skip_serializing_if = "Option::is_none")]
68 pub etag: Option<String>,
69 #[serde(skip_serializing_if = "Option::is_none")]
70 pub last_modified: Option<String>,
71 #[serde(skip_serializing_if = "std::ops::Not::not", default)]
72 pub not_modified: bool,
73 #[serde(skip_serializing_if = "Option::is_none")]
75 pub engine: Option<String>,
76 #[serde(skip_serializing_if = "Option::is_none")]
78 pub browser_engine: Option<String>,
79 #[serde(skip_serializing_if = "Option::is_none")]
81 pub browser_fingerprint: Option<String>,
82 #[serde(skip_serializing_if = "Option::is_none")]
84 pub itna: Option<Value>,
85 #[serde(skip_serializing_if = "Vec::is_empty", default)]
86 pub warnings: Vec<String>,
87 #[serde(skip_serializing_if = "BTreeMap::is_empty", default)]
89 pub timings: BTreeMap<String, f64>,
90 #[serde(skip_serializing_if = "Option::is_none")]
92 pub ocr: Option<OcrMeta>,
93 #[serde(skip_serializing_if = "Option::is_none")]
95 pub duplicate_of: Option<String>,
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub relevance: Option<f32>,
99 #[serde(skip_serializing_if = "Option::is_none")]
101 pub crawl: Option<CrawlTrace>,
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub query_filter: Option<QueryFilterStats>,
105 #[serde(skip_serializing_if = "Vec::is_empty", default)]
107 pub json_ld: Vec<Value>,
108 #[serde(skip_serializing_if = "Option::is_none")]
111 pub plan: Option<PlanTrace>,
112}
113
114#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
116#[serde(rename_all = "camelCase")]
117pub struct PlanTrace {
118 pub steps: Vec<PlanStep>,
119}
120
121#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
122#[serde(rename_all = "camelCase")]
123pub struct PlanStep {
124 pub action: String,
126 pub chosen: bool,
127 pub learned: bool,
129 #[serde(skip_serializing_if = "Option::is_none")]
131 pub p: Option<f64>,
132 #[serde(skip_serializing_if = "Option::is_none")]
134 pub value: Option<f64>,
135 #[serde(skip_serializing_if = "Option::is_none")]
137 pub charge: Option<f64>,
138 #[serde(skip_serializing_if = "Option::is_none")]
140 pub quality: Option<f64>,
141 #[serde(skip_serializing_if = "Option::is_none")]
143 pub blocks: Option<[usize; 3]>, }
145
146#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
147#[serde(rename_all = "camelCase")]
148pub struct QueryFilterStats {
149 pub kept_blocks: usize,
150 pub total_blocks: usize,
151 pub tokens_before: usize,
152 pub tokens_after: usize,
153}
154
155#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
157#[serde(rename_all = "camelCase")]
158pub struct ChangeTracking {
159 pub previous_scrape_at: Option<String>,
160 pub change_status: String,
162 pub visibility: String,
164 #[serde(skip_serializing_if = "Option::is_none")]
165 pub diff: Option<Value>,
166 #[serde(skip_serializing_if = "Option::is_none")]
167 pub json: Option<Value>,
168 #[serde(skip_serializing_if = "Option::is_none")]
169 pub pagesift: Option<Value>,
170}
171
172#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
173#[serde(rename_all = "camelCase")]
174pub struct Metadata {
175 #[serde(skip_serializing_if = "Option::is_none")]
177 pub scrape_id: Option<String>,
178 #[serde(skip_serializing_if = "Option::is_none")]
179 pub title: Option<String>,
180 #[serde(skip_serializing_if = "Option::is_none")]
181 pub description: Option<String>,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 pub language: Option<String>,
184 #[serde(skip_serializing_if = "Option::is_none")]
185 pub keywords: Option<String>,
186 #[serde(skip_serializing_if = "Option::is_none")]
187 pub robots: Option<String>,
188 #[serde(skip_serializing_if = "Option::is_none")]
189 pub favicon: Option<String>,
190 #[serde(skip_serializing_if = "Option::is_none")]
191 pub published_time: Option<String>,
192 #[serde(skip_serializing_if = "Option::is_none")]
193 pub author: Option<String>,
194 #[serde(skip_serializing_if = "Option::is_none")]
195 pub modified_time: Option<String>,
196 #[serde(skip_serializing_if = "Option::is_none")]
197 pub url: Option<String>,
198 #[serde(rename = "sourceURL", skip_serializing_if = "Option::is_none")]
199 pub source_url: Option<String>,
200 pub status_code: u16,
201 #[serde(skip)]
203 pub retry_after: bool,
204 #[serde(skip_serializing_if = "Option::is_none")]
205 pub content_type: Option<String>,
206 #[serde(skip_serializing_if = "Option::is_none")]
207 pub error: Option<String>,
208 pub proxy_used: String,
209 #[serde(skip_serializing_if = "Option::is_none")]
210 pub cache_state: Option<String>,
211 #[serde(skip_serializing_if = "Option::is_none")]
212 pub cached_at: Option<String>,
213 #[serde(flatten)]
214 pub extra: BTreeMap<String, Value>,
215 #[serde(skip_serializing_if = "Option::is_none")]
216 pub pagesift: Option<PagesiftMeta>,
217}
218
219#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
220#[serde(rename_all = "camelCase")]
221pub struct Document {
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub markdown: Option<String>,
224 #[serde(skip_serializing_if = "Option::is_none")]
226 pub pages: Option<Vec<PageMarkdown>>,
227 #[serde(skip_serializing_if = "Option::is_none")]
228 pub html: Option<String>,
229 #[serde(skip_serializing_if = "Option::is_none")]
230 pub raw_html: Option<String>,
231 #[serde(skip_serializing_if = "Option::is_none")]
232 pub links: Option<Vec<String>>,
233 #[serde(skip)]
235 pub link_text: Option<Vec<String>>,
236 #[serde(skip)]
238 pub alternates: Vec<(String, String)>,
239 #[serde(skip)]
242 pub quality: Option<f64>,
243 #[serde(skip_serializing_if = "Option::is_none")]
244 pub images: Option<Vec<String>>,
245 #[serde(skip_serializing_if = "Option::is_none")]
246 pub screenshot: Option<String>,
247 #[serde(skip_serializing_if = "Option::is_none")]
248 pub json: Option<Value>,
249 #[serde(skip_serializing_if = "Option::is_none")]
251 pub extract: Option<Value>,
252 #[serde(skip_serializing_if = "Option::is_none")]
253 pub summary: Option<String>,
254 #[serde(skip_serializing_if = "Option::is_none")]
255 pub actions: Option<Value>,
256 #[serde(skip_serializing_if = "Option::is_none")]
257 pub warning: Option<String>,
258 #[serde(skip_serializing_if = "Option::is_none")]
259 pub change_tracking: Option<ChangeTracking>,
260 #[serde(skip_serializing_if = "Option::is_none")]
261 pub chunks: Option<Vec<DocChunk>>,
262 #[serde(skip_serializing_if = "Vec::is_empty", default)]
265 pub attachments: Vec<super::Attachment>,
266 pub metadata: Metadata,
267}
268
269#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
271#[serde(rename_all = "camelCase")]
272pub struct PageMarkdown {
273 pub page_number: usize,
275 pub markdown: String,
276}
277
278#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
279#[serde(rename_all = "camelCase")]
280pub struct DocChunk {
281 pub text: String,
282 pub heading_path: Vec<String>,
283 pub start: usize,
284 pub end: usize,
285 pub tokens: usize,
286}
287
288#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
289pub struct MapLink {
290 pub url: String,
291 #[serde(skip_serializing_if = "Option::is_none")]
292 pub title: Option<String>,
293 #[serde(skip_serializing_if = "Option::is_none")]
294 pub description: Option<String>,
295}
296
297#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
298pub struct ScrapeResponse {
299 pub success: bool,
300 pub data: Document,
301 #[serde(skip_serializing_if = "Option::is_none")]
302 pub warning: Option<String>,
303}
304
305#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
306#[serde(rename_all = "camelCase")]
307pub struct JobStarted {
308 pub success: bool,
309 pub id: String,
310 pub url: String,
311 #[serde(rename = "invalidURLs", skip_serializing_if = "Option::is_none")]
312 pub invalid_urls: Option<Vec<String>>,
313 #[serde(default, skip_serializing_if = "Vec::is_empty")]
315 pub warnings: Vec<String>,
316}
317
318#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
319#[serde(rename_all = "camelCase")]
320pub struct JobStatus {
321 pub success: bool,
322 pub status: String,
323 pub completed: usize,
324 pub total: usize,
325 pub credits_used: usize,
326 pub expires_at: String,
327 #[serde(skip_serializing_if = "Option::is_none")]
328 pub next: Option<String>,
329 pub data: Vec<Document>,
330 #[serde(skip_serializing_if = "Option::is_none")]
331 pub pagesift: Option<CrawlSummary>,
332}
333
334#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
335pub struct JobError {
336 pub id: String,
337 pub timestamp: String,
338 pub url: String,
339 pub code: String,
340 pub error: String,
341}
342
343#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
344#[serde(rename_all = "camelCase")]
345pub struct JobErrors {
346 pub errors: Vec<JobError>,
347 pub robots_blocked: Vec<String>,
348}
349
350#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
351pub struct MapResponse {
352 pub success: bool,
353 pub links: Vec<MapLink>,
354 #[serde(default, skip_serializing_if = "Vec::is_empty")]
356 pub warnings: Vec<String>,
357}