1use std::collections::BTreeMap;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
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)]
25#[serde(rename_all = "camelCase")]
26pub struct PagesiftMeta {
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub content_hash: Option<String>,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub raw_hash: Option<String>,
31 #[serde(skip_serializing_if = "Option::is_none")]
32 pub text_hash: Option<String>,
33 #[serde(skip_serializing_if = "Vec::is_empty", default)]
34 pub redirect_chain: Vec<String>,
35 #[serde(skip_serializing_if = "Option::is_none")]
36 pub etag: Option<String>,
37 #[serde(skip_serializing_if = "Option::is_none")]
38 pub last_modified: Option<String>,
39 #[serde(skip_serializing_if = "std::ops::Not::not", default)]
40 pub not_modified: bool,
41 #[serde(skip_serializing_if = "Option::is_none")]
43 pub engine: Option<String>,
44 #[serde(skip_serializing_if = "Option::is_none")]
46 pub browser_engine: Option<String>,
47 #[serde(skip_serializing_if = "Vec::is_empty", default)]
48 pub warnings: Vec<String>,
49 #[serde(skip_serializing_if = "BTreeMap::is_empty", default)]
51 pub timings: BTreeMap<String, f64>,
52 #[serde(skip_serializing_if = "Option::is_none")]
54 pub duplicate_of: Option<String>,
55 #[serde(skip_serializing_if = "Option::is_none")]
57 pub relevance: Option<f32>,
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub query_filter: Option<QueryFilterStats>,
61}
62
63#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
64#[serde(rename_all = "camelCase")]
65pub struct QueryFilterStats {
66 pub kept_blocks: usize,
67 pub total_blocks: usize,
68 pub tokens_before: usize,
69 pub tokens_after: usize,
70}
71
72#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
74#[serde(rename_all = "camelCase")]
75pub struct ChangeTracking {
76 pub previous_scrape_at: Option<String>,
77 pub change_status: String,
79 pub visibility: String,
81 #[serde(skip_serializing_if = "Option::is_none")]
82 pub diff: Option<Value>,
83 #[serde(skip_serializing_if = "Option::is_none")]
84 pub json: Option<Value>,
85 #[serde(skip_serializing_if = "Option::is_none")]
86 pub pagesift: Option<Value>,
87}
88
89#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
90#[serde(rename_all = "camelCase")]
91pub struct Metadata {
92 #[serde(skip_serializing_if = "Option::is_none")]
93 pub title: Option<String>,
94 #[serde(skip_serializing_if = "Option::is_none")]
95 pub description: Option<String>,
96 #[serde(skip_serializing_if = "Option::is_none")]
97 pub language: Option<String>,
98 #[serde(skip_serializing_if = "Option::is_none")]
99 pub keywords: Option<String>,
100 #[serde(skip_serializing_if = "Option::is_none")]
101 pub robots: Option<String>,
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub favicon: Option<String>,
104 #[serde(skip_serializing_if = "Option::is_none")]
105 pub published_time: Option<String>,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 pub author: Option<String>,
108 #[serde(skip_serializing_if = "Option::is_none")]
109 pub modified_time: Option<String>,
110 #[serde(skip_serializing_if = "Option::is_none")]
111 pub url: Option<String>,
112 #[serde(rename = "sourceURL", skip_serializing_if = "Option::is_none")]
113 pub source_url: Option<String>,
114 pub status_code: u16,
115 #[serde(skip_serializing_if = "Option::is_none")]
116 pub content_type: Option<String>,
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub error: Option<String>,
119 pub proxy_used: String,
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub cache_state: Option<String>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub cached_at: Option<String>,
124 #[serde(flatten)]
125 pub extra: BTreeMap<String, Value>,
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub pagesift: Option<PagesiftMeta>,
128}
129
130#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
131#[serde(rename_all = "camelCase")]
132pub struct Document {
133 #[serde(skip_serializing_if = "Option::is_none")]
134 pub markdown: Option<String>,
135 #[serde(skip_serializing_if = "Option::is_none")]
136 pub html: Option<String>,
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub raw_html: Option<String>,
139 #[serde(skip_serializing_if = "Option::is_none")]
140 pub links: Option<Vec<String>>,
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub images: Option<Vec<String>>,
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub screenshot: Option<String>,
145 #[serde(skip_serializing_if = "Option::is_none")]
146 pub json: Option<Value>,
147 #[serde(skip_serializing_if = "Option::is_none")]
148 pub summary: Option<String>,
149 #[serde(skip_serializing_if = "Option::is_none")]
150 pub actions: Option<Value>,
151 #[serde(skip_serializing_if = "Option::is_none")]
152 pub warning: Option<String>,
153 #[serde(skip_serializing_if = "Option::is_none")]
154 pub change_tracking: Option<ChangeTracking>,
155 #[serde(skip_serializing_if = "Option::is_none")]
156 pub chunks: Option<Vec<DocChunk>>,
157 pub metadata: Metadata,
158}
159
160#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
161#[serde(rename_all = "camelCase")]
162pub struct DocChunk {
163 pub text: String,
164 pub heading_path: Vec<String>,
165 pub start: usize,
166 pub end: usize,
167 pub tokens: usize,
168}
169
170#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
171pub struct MapLink {
172 pub url: String,
173 #[serde(skip_serializing_if = "Option::is_none")]
174 pub title: Option<String>,
175 #[serde(skip_serializing_if = "Option::is_none")]
176 pub description: Option<String>,
177}
178
179#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
180pub struct ScrapeResponse {
181 pub success: bool,
182 pub data: Document,
183 #[serde(skip_serializing_if = "Option::is_none")]
184 pub warning: Option<String>,
185}
186
187#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
188#[serde(rename_all = "camelCase")]
189pub struct JobStarted {
190 pub success: bool,
191 pub id: String,
192 pub url: String,
193 #[serde(rename = "invalidURLs", skip_serializing_if = "Option::is_none")]
194 pub invalid_urls: Option<Vec<String>>,
195}
196
197#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
198#[serde(rename_all = "camelCase")]
199pub struct JobStatus {
200 pub success: bool,
201 pub status: String,
202 pub completed: usize,
203 pub total: usize,
204 pub credits_used: usize,
205 pub expires_at: String,
206 #[serde(skip_serializing_if = "Option::is_none")]
207 pub next: Option<String>,
208 pub data: Vec<Document>,
209 #[serde(skip_serializing_if = "Option::is_none")]
210 pub pagesift: Option<CrawlSummary>,
211}
212
213#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
214pub struct JobError {
215 pub id: String,
216 pub timestamp: String,
217 pub url: String,
218 pub code: String,
219 pub error: String,
220}
221
222#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
223#[serde(rename_all = "camelCase")]
224pub struct JobErrors {
225 pub errors: Vec<JobError>,
226 pub robots_blocked: Vec<String>,
227}
228
229#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
230pub struct MapResponse {
231 pub success: bool,
232 pub links: Vec<MapLink>,
233}