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,
13 #[serde(skip_serializing_if = "Option::is_none")]
15 pub coverage: Option<f64>,
16 #[serde(skip_serializing_if = "BTreeMap::is_empty", default)]
18 pub term_evidence: BTreeMap<String, usize>,
19 pub pages: usize,
21}
22
23#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
26#[serde(rename_all = "camelCase")]
27pub struct CrawlTrace {
28 pub depth: usize,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub parent: Option<String>,
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub score: Option<f32>,
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub attachment_of: Option<String>,
39}
40
41#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
42#[serde(rename_all = "camelCase")]
43pub struct PagesiftMeta {
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub content_hash: Option<String>,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub raw_hash: Option<String>,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub text_hash: Option<String>,
50 #[serde(skip_serializing_if = "Vec::is_empty", default)]
51 pub redirect_chain: Vec<String>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub etag: Option<String>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub last_modified: Option<String>,
56 #[serde(skip_serializing_if = "std::ops::Not::not", default)]
57 pub not_modified: bool,
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub engine: Option<String>,
61 #[serde(skip_serializing_if = "Option::is_none")]
63 pub browser_engine: Option<String>,
64 #[serde(skip_serializing_if = "Vec::is_empty", default)]
65 pub warnings: Vec<String>,
66 #[serde(skip_serializing_if = "BTreeMap::is_empty", default)]
68 pub timings: BTreeMap<String, f64>,
69 #[serde(skip_serializing_if = "Option::is_none")]
71 pub duplicate_of: Option<String>,
72 #[serde(skip_serializing_if = "Option::is_none")]
74 pub relevance: Option<f32>,
75 #[serde(skip_serializing_if = "Option::is_none")]
77 pub crawl: Option<CrawlTrace>,
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub query_filter: Option<QueryFilterStats>,
81 #[serde(skip_serializing_if = "Vec::is_empty", default)]
83 pub json_ld: Vec<Value>,
84}
85
86#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
87#[serde(rename_all = "camelCase")]
88pub struct QueryFilterStats {
89 pub kept_blocks: usize,
90 pub total_blocks: usize,
91 pub tokens_before: usize,
92 pub tokens_after: usize,
93}
94
95#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
97#[serde(rename_all = "camelCase")]
98pub struct ChangeTracking {
99 pub previous_scrape_at: Option<String>,
100 pub change_status: String,
102 pub visibility: String,
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub diff: Option<Value>,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub json: Option<Value>,
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub pagesift: Option<Value>,
110}
111
112#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
113#[serde(rename_all = "camelCase")]
114pub struct Metadata {
115 #[serde(skip_serializing_if = "Option::is_none")]
116 pub title: Option<String>,
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub description: Option<String>,
119 #[serde(skip_serializing_if = "Option::is_none")]
120 pub language: Option<String>,
121 #[serde(skip_serializing_if = "Option::is_none")]
122 pub keywords: Option<String>,
123 #[serde(skip_serializing_if = "Option::is_none")]
124 pub robots: Option<String>,
125 #[serde(skip_serializing_if = "Option::is_none")]
126 pub favicon: Option<String>,
127 #[serde(skip_serializing_if = "Option::is_none")]
128 pub published_time: Option<String>,
129 #[serde(skip_serializing_if = "Option::is_none")]
130 pub author: Option<String>,
131 #[serde(skip_serializing_if = "Option::is_none")]
132 pub modified_time: Option<String>,
133 #[serde(skip_serializing_if = "Option::is_none")]
134 pub url: Option<String>,
135 #[serde(rename = "sourceURL", skip_serializing_if = "Option::is_none")]
136 pub source_url: Option<String>,
137 pub status_code: u16,
138 #[serde(skip_serializing_if = "Option::is_none")]
139 pub content_type: Option<String>,
140 #[serde(skip_serializing_if = "Option::is_none")]
141 pub error: Option<String>,
142 pub proxy_used: String,
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub cache_state: Option<String>,
145 #[serde(skip_serializing_if = "Option::is_none")]
146 pub cached_at: Option<String>,
147 #[serde(flatten)]
148 pub extra: BTreeMap<String, Value>,
149 #[serde(skip_serializing_if = "Option::is_none")]
150 pub pagesift: Option<PagesiftMeta>,
151}
152
153#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
154#[serde(rename_all = "camelCase")]
155pub struct Document {
156 #[serde(skip_serializing_if = "Option::is_none")]
157 pub markdown: Option<String>,
158 #[serde(skip_serializing_if = "Option::is_none")]
160 pub pages: Option<Vec<PageMarkdown>>,
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub html: Option<String>,
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub raw_html: Option<String>,
165 #[serde(skip_serializing_if = "Option::is_none")]
166 pub links: Option<Vec<String>>,
167 #[serde(skip)]
169 pub link_text: Option<Vec<String>>,
170 #[serde(skip)]
172 pub alternates: Vec<(String, String)>,
173 #[serde(skip_serializing_if = "Option::is_none")]
174 pub images: Option<Vec<String>>,
175 #[serde(skip_serializing_if = "Option::is_none")]
176 pub screenshot: Option<String>,
177 #[serde(skip_serializing_if = "Option::is_none")]
178 pub json: Option<Value>,
179 #[serde(skip_serializing_if = "Option::is_none")]
180 pub summary: Option<String>,
181 #[serde(skip_serializing_if = "Option::is_none")]
182 pub actions: Option<Value>,
183 #[serde(skip_serializing_if = "Option::is_none")]
184 pub warning: Option<String>,
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub change_tracking: Option<ChangeTracking>,
187 #[serde(skip_serializing_if = "Option::is_none")]
188 pub chunks: Option<Vec<DocChunk>>,
189 pub metadata: Metadata,
190}
191
192#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
194#[serde(rename_all = "camelCase")]
195pub struct PageMarkdown {
196 pub page_number: usize,
198 pub markdown: String,
199}
200
201#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
202#[serde(rename_all = "camelCase")]
203pub struct DocChunk {
204 pub text: String,
205 pub heading_path: Vec<String>,
206 pub start: usize,
207 pub end: usize,
208 pub tokens: usize,
209}
210
211#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
212pub struct MapLink {
213 pub url: String,
214 #[serde(skip_serializing_if = "Option::is_none")]
215 pub title: Option<String>,
216 #[serde(skip_serializing_if = "Option::is_none")]
217 pub description: Option<String>,
218}
219
220#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
221pub struct ScrapeResponse {
222 pub success: bool,
223 pub data: Document,
224 #[serde(skip_serializing_if = "Option::is_none")]
225 pub warning: Option<String>,
226}
227
228#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
229#[serde(rename_all = "camelCase")]
230pub struct JobStarted {
231 pub success: bool,
232 pub id: String,
233 pub url: String,
234 #[serde(rename = "invalidURLs", skip_serializing_if = "Option::is_none")]
235 pub invalid_urls: Option<Vec<String>>,
236}
237
238#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
239#[serde(rename_all = "camelCase")]
240pub struct JobStatus {
241 pub success: bool,
242 pub status: String,
243 pub completed: usize,
244 pub total: usize,
245 pub credits_used: usize,
246 pub expires_at: String,
247 #[serde(skip_serializing_if = "Option::is_none")]
248 pub next: Option<String>,
249 pub data: Vec<Document>,
250 #[serde(skip_serializing_if = "Option::is_none")]
251 pub pagesift: Option<CrawlSummary>,
252}
253
254#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
255pub struct JobError {
256 pub id: String,
257 pub timestamp: String,
258 pub url: String,
259 pub code: String,
260 pub error: String,
261}
262
263#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
264#[serde(rename_all = "camelCase")]
265pub struct JobErrors {
266 pub errors: Vec<JobError>,
267 pub robots_blocked: Vec<String>,
268}
269
270#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
271pub struct MapResponse {
272 pub success: bool,
273 pub links: Vec<MapLink>,
274}