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_serializing_if = "Option::is_none")]
171 pub images: Option<Vec<String>>,
172 #[serde(skip_serializing_if = "Option::is_none")]
173 pub screenshot: Option<String>,
174 #[serde(skip_serializing_if = "Option::is_none")]
175 pub json: Option<Value>,
176 #[serde(skip_serializing_if = "Option::is_none")]
177 pub summary: Option<String>,
178 #[serde(skip_serializing_if = "Option::is_none")]
179 pub actions: Option<Value>,
180 #[serde(skip_serializing_if = "Option::is_none")]
181 pub warning: Option<String>,
182 #[serde(skip_serializing_if = "Option::is_none")]
183 pub change_tracking: Option<ChangeTracking>,
184 #[serde(skip_serializing_if = "Option::is_none")]
185 pub chunks: Option<Vec<DocChunk>>,
186 pub metadata: Metadata,
187}
188
189#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
191#[serde(rename_all = "camelCase")]
192pub struct PageMarkdown {
193 pub page_number: usize,
195 pub markdown: String,
196}
197
198#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
199#[serde(rename_all = "camelCase")]
200pub struct DocChunk {
201 pub text: String,
202 pub heading_path: Vec<String>,
203 pub start: usize,
204 pub end: usize,
205 pub tokens: usize,
206}
207
208#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
209pub struct MapLink {
210 pub url: String,
211 #[serde(skip_serializing_if = "Option::is_none")]
212 pub title: Option<String>,
213 #[serde(skip_serializing_if = "Option::is_none")]
214 pub description: Option<String>,
215}
216
217#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
218pub struct ScrapeResponse {
219 pub success: bool,
220 pub data: Document,
221 #[serde(skip_serializing_if = "Option::is_none")]
222 pub warning: Option<String>,
223}
224
225#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
226#[serde(rename_all = "camelCase")]
227pub struct JobStarted {
228 pub success: bool,
229 pub id: String,
230 pub url: String,
231 #[serde(rename = "invalidURLs", skip_serializing_if = "Option::is_none")]
232 pub invalid_urls: Option<Vec<String>>,
233}
234
235#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
236#[serde(rename_all = "camelCase")]
237pub struct JobStatus {
238 pub success: bool,
239 pub status: String,
240 pub completed: usize,
241 pub total: usize,
242 pub credits_used: usize,
243 pub expires_at: String,
244 #[serde(skip_serializing_if = "Option::is_none")]
245 pub next: Option<String>,
246 pub data: Vec<Document>,
247 #[serde(skip_serializing_if = "Option::is_none")]
248 pub pagesift: Option<CrawlSummary>,
249}
250
251#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
252pub struct JobError {
253 pub id: String,
254 pub timestamp: String,
255 pub url: String,
256 pub code: String,
257 pub error: String,
258}
259
260#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
261#[serde(rename_all = "camelCase")]
262pub struct JobErrors {
263 pub errors: Vec<JobError>,
264 pub robots_blocked: Vec<String>,
265}
266
267#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
268pub struct MapResponse {
269 pub success: bool,
270 pub links: Vec<MapLink>,
271}