1use chrono::Utc;
8use serde::Deserialize;
9use std::collections::BTreeMap;
10
11#[derive(Clone, Debug, Deserialize)]
12pub struct Response {
13 pub message: Option<String>,
14 pub response: Option<SearchResponse>,
15}
16
17#[derive(Clone, Debug, Deserialize)]
18#[serde(rename_all = "camelCase")]
19pub struct SearchResponse {
20 pub status: Option<String>,
21 pub user_tier: Option<String>,
22 pub total: Option<u32>,
23 pub start_index: Option<u32>,
24 pub page_size: Option<u32>,
25 pub current_page: Option<u32>,
26 pub pages: Option<isize>,
27 pub order_by: Option<String>,
28 pub results: Option<Vec<SearchResult>>,
29 pub message: Option<String>,
30 pub content: Option<Content>,
31}
32
33#[derive(Clone, Debug, Deserialize)]
34#[serde(rename_all = "camelCase")]
35pub struct Fields {
36 pub byline: Option<String>,
37 pub short_url: Option<String>,
38 pub trail_text: Option<String>,
39 pub headline: Option<String>,
40 pub body: Option<String>,
41 pub body_text: Option<String>,
42 pub last_modified: Option<chrono::DateTime<Utc>>,
43 pub has_story_package: Option<String>,
44 pub score: Option<String>,
45 pub standfirst: Option<String>,
46 pub show_in_related_content: Option<String>,
47 pub thumbnail: Option<String>,
48 pub wordcount: Option<String>,
49 pub commentable: Option<String>,
50 pub is_premoderated: Option<String>,
51 pub allow_ugc: Option<String>,
52 pub publication: Option<String>,
53 pub internal_page_code: Option<String>,
54 pub production_office: Option<String>,
55 pub should_hide_adverts: Option<String>,
56 pub live_blogging_now: Option<String>,
57 pub comment_close_date: Option<chrono::DateTime<Utc>>,
58 pub star_rating: Option<String>,
59}
60
61#[derive(Clone, Debug, Deserialize)]
62#[serde(rename_all = "camelCase")]
63pub struct Tag {
64 pub id: String,
65 pub r#type: String,
66 pub web_title: String,
67 pub web_url: String,
68 pub api_url: String,
69 pub references: Vec<Reference>,
70 pub bio: Option<String>,
71 pub byline_image_url: Option<String>,
72 pub byline_large_image_url: Option<String>,
73 pub first_name: Option<String>,
74 pub last_name: Option<String>,
75 pub email_address: Option<String>,
76 pub twitter_handle: Option<String>,
77 pub section_id: Option<String>,
78 pub section_name: Option<String>,
79 pub description: Option<String>,
80 pub paid_content_type: Option<String>,
81 pub paid_content_type_campaign_colour: Option<String>,
82 pub rcs_id: Option<String>,
83 pub r2_contributor_id: Option<String>,
84 pub tag_categories: Option<Vec<String>>,
85 pub entity_ids: Option<Vec<String>>,
86 pub campaign_information_type: Option<String>,
87 pub internal_name: Option<String>,
88}
89
90#[derive(Clone, Debug, Deserialize)]
91#[serde(rename_all = "camelCase")]
92pub struct SearchResult {
93 pub id: String,
94 pub r#type: Option<String>,
95 pub section_id: Option<String>,
96 pub section_name: Option<String>,
97 pub web_publication_date: Option<chrono::DateTime<Utc>>,
98 pub web_title: String,
99 pub web_url: String,
100 pub api_url: String,
101 pub is_hosted: Option<bool>,
102 pub pillar_id: Option<String>,
103 pub pillar_name: Option<String>,
104 pub fields: Option<Fields>,
105 pub tags: Option<Vec<Tag>>,
106 pub section: Option<Section>,
107 pub blocks: Option<Blocks>,
108 pub editions: Option<Vec<Edition>>,
109}
110
111#[derive(Clone, Debug, Deserialize)]
112pub struct Reference {
113 pub id: String,
114 pub r#type: String,
115}
116
117#[derive(Clone, Debug, Deserialize)]
118#[serde(rename_all = "camelCase")]
119pub struct Section {
120 pub id: String,
121 pub web_title: String,
122 pub web_url: String,
123 pub api_url: String,
124 pub editions: Vec<Edition>,
125}
126
127#[derive(Clone, Debug, Deserialize)]
128#[serde(rename_all = "camelCase")]
129pub struct Edition {
130 pub id: String,
131 pub web_title: String,
132 pub web_url: String,
133 pub api_url: String,
134 pub code: String,
135}
136
137#[derive(Clone, Debug, Deserialize)]
138#[serde(rename_all = "camelCase")]
139pub struct Blocks {
140 pub main: Option<Block>,
141 pub body: Option<Vec<Block>>,
142 pub total_body_blocks: Option<i32>,
143 pub requested_body_blocks: Option<BTreeMap<String, Vec<Block>>>,
144}
145
146#[derive(Clone, Debug, Deserialize)]
147#[serde(rename_all = "camelCase")]
148pub struct Block {
149 pub id: String,
150 pub body_html: String,
151 pub body_text_summary: String,
152 pub title: Option<String>,
153 pub attributes: BlockAttributes,
154 pub published: bool,
155 pub created_date: Option<serde_json::Value>,
156 pub first_published_date: Option<serde_json::Value>,
157 pub published_date: Option<serde_json::Value>,
158 pub last_modified_date: Option<serde_json::Value>,
159 pub contributors: Vec<String>,
160 pub elements: Vec<BlockElement>,
161}
162
163#[derive(Clone, Debug, Deserialize)]
164#[serde(rename_all = "camelCase")]
165pub struct BlockElement {
166 pub r#type: String,
167 pub assets: Vec<Asset>,
168 pub text_type_data: Option<TextElementFields>,
169 pub video_type_data: Option<VideoElementFields>,
170 pub tweet_type_data: Option<TweetElementFields>,
171 pub image_type_data: Option<ImageElementFields>,
172 pub audio_type_data: Option<AudioElementFields>,
173 pub pullquote_type_data: Option<PullquoteElementFields>,
174 pub interactive_type_data: Option<InteractiveElementFields>,
175 pub map_type_data: Option<StandardElementFields>,
176 pub document_type_data: Option<StandardElementFields>,
177 pub table_type_data: Option<StandardElementFields>,
178 pub witness_type_data: Option<WitnessElementFields>,
179 pub rich_link_type_data: Option<RichLinkElementFields>,
180 pub membership_type_data: Option<MembershipElementFields>,
181 pub embed_type_data: Option<EmbedElementFields>,
182 pub instagram_type_data: Option<InstagramElementFields>,
183 pub comment_type_data: Option<CommentElementFields>,
184 pub vine_type_data: Option<VineElementFields>,
185 pub content_atom_type_data: Option<ContentAtomElementFields>,
186 pub tracking: Option<Box<EmbedTracking>>,
187 pub code_type_data: Option<CodeElementFields>,
188}
189
190#[derive(Clone, Debug, Deserialize)]
191#[serde(rename_all = "camelCase")]
192pub struct TextElementFields {
193 pub html: Option<String>,
194 pub role: Option<String>,
195}
196
197#[derive(Clone, Debug, Deserialize)]
198#[serde(rename_all = "camelCase")]
199pub struct VideoElementFields {
200 pub url: Option<String>,
201 pub description: Option<String>,
202 pub title: Option<String>,
203 pub html: Option<String>,
204 pub source: Option<String>,
205 pub credit: Option<String>,
206 pub caption: Option<String>,
207 pub height: Option<i32>,
208 pub width: Option<i32>,
209 pub duration: Option<i32>,
210 pub content_auth_system: Option<String>,
211 pub embeddable: Option<String>,
212 pub is_inappropriate_for_adverts: Option<bool>,
213 pub media_id: Option<String>,
214 pub still_image_url: Option<String>,
215 pub thumbnail_url: Option<String>,
216 pub short_url: Option<String>,
217 pub role: Option<String>,
218 pub original_url: Option<String>,
219 pub source_domain: Option<String>,
220}
221
222#[derive(Clone, Debug, Deserialize)]
223#[serde(rename_all = "camelCase")]
224pub struct TweetElementFields {
225 pub source: Option<String>,
226 pub url: Option<String>,
227 pub id: Option<String>,
228 pub html: Option<String>,
229 pub original_url: Option<String>,
230 pub role: Option<String>,
231 pub source_domain: Option<String>,
232}
233
234#[derive(Clone, Debug, Deserialize)]
235#[serde(rename_all = "camelCase")]
236pub struct ImageElementFields {
237 pub caption: Option<String>,
238 pub copyright: Option<String>,
239 pub display_credit: Option<bool>,
240 pub credit: Option<String>,
241 pub source: Option<String>,
242 pub photographer: Option<String>,
243 pub alt: Option<String>,
244 pub media_id: Option<String>,
245 pub media_api_uri: Option<String>,
246 pub picdar_urn: Option<String>,
247 pub suppliers_reference: Option<String>,
248 pub image_type: Option<String>,
249 pub comment: Option<String>,
250 pub role: Option<String>,
251}
252
253#[derive(Clone, Debug, Deserialize)]
254#[serde(rename_all = "camelCase")]
255pub struct AudioElementFields {
256 pub html: Option<String>,
257 pub source: Option<String>,
258 pub description: Option<String>,
259 pub title: Option<String>,
260 pub credit: Option<String>,
261 pub caption: Option<String>,
262 pub duration_minutes: Option<i32>,
263 pub duration_seconds: Option<i32>,
264 pub clean: Option<bool>,
265 pub explicit: Option<bool>,
266 pub role: Option<String>,
267 pub source_domain: Option<String>,
268}
269
270#[derive(Clone, Debug, Deserialize)]
271#[serde(rename_all = "camelCase")]
272pub struct PullquoteElementFields {
273 pub html: Option<String>,
274 pub attribution: Option<String>,
275 pub role: Option<String>,
276 pub source: Option<String>,
277 pub source_domain: Option<String>,
278}
279
280#[derive(Clone, Debug, Deserialize)]
281#[serde(rename_all = "camelCase")]
282pub struct InteractiveElementFields {
283 pub url: Option<String>,
284 pub original_url: Option<String>,
285 pub source: Option<String>,
286 pub caption: Option<String>,
287 pub alt: Option<String>,
288 pub script_url: Option<String>,
289 pub html: Option<String>,
290 pub script_name: Option<String>,
291 pub iframe_url: Option<String>,
292 pub role: Option<String>,
293 pub is_mandatory: Option<bool>,
294 pub source_domain: Option<String>,
295}
296
297#[derive(Clone, Debug, Deserialize)]
298#[serde(rename_all = "camelCase")]
299pub struct StandardElementFields {
300 pub url: Option<String>,
301 pub original_url: Option<String>,
302 pub source: Option<String>,
303 pub title: Option<String>,
304 pub description: Option<String>,
305 pub credit: Option<String>,
306 pub caption: Option<String>,
307 pub width: Option<i32>,
308 pub height: Option<i32>,
309 pub html: Option<String>,
310 pub role: Option<String>,
311 pub is_mandatory: Option<bool>,
312 pub source_domain: Option<String>,
313}
314
315#[derive(Clone, Debug, Deserialize)]
316#[serde(rename_all = "camelCase")]
317pub struct WitnessElementFields {
318 pub url: Option<String>,
319 pub original_url: Option<String>,
320 pub witness_embed_type: Option<String>,
321 pub media_id: Option<String>,
322 pub source: Option<String>,
323 pub title: Option<String>,
324 pub description: Option<String>,
325 pub author_name: Option<String>,
326 pub author_username: Option<String>,
327 pub author_witness_profile_url: Option<String>,
328 pub author_guardian_profile_url: Option<String>,
329 pub caption: Option<String>,
330 pub alt: Option<String>,
331 pub width: Option<i32>,
332 pub height: Option<i32>,
333 pub html: Option<String>,
334 pub api_url: Option<String>,
335 pub photographer: Option<String>,
336 pub date_created: Option<chrono::DateTime<Utc>>,
337 pub youtube_url: Option<String>,
338 pub youtube_source: Option<String>,
339 pub youtube_title: Option<String>,
340 pub youtube_description: Option<String>,
341 pub youtube_author_name: Option<String>,
342 pub youtube_html: Option<String>,
343 pub role: Option<String>,
344 pub source_domain: Option<String>,
345}
346
347#[derive(Clone, Debug, Deserialize)]
348#[serde(rename_all = "camelCase")]
349pub struct RichLinkElementFields {
350 pub url: Option<String>,
351 pub original_url: Option<String>,
352 pub link_text: Option<String>,
353 pub link_prefix: Option<String>,
354 pub role: Option<String>,
355 pub sponsorship: Option<String>,
356}
357
358#[derive(Clone, Debug, Deserialize)]
359#[serde(rename_all = "camelCase")]
360pub struct MembershipElementFields {
361 pub original_url: Option<String>,
362 pub link_text: Option<String>,
363 pub link_prefix: Option<String>,
364 pub title: Option<String>,
365 pub venue: Option<String>,
366 pub location: Option<String>,
367 pub identifier: Option<String>,
368 pub image: Option<String>,
369 pub price: Option<String>,
370 pub start: Option<chrono::DateTime<Utc>>,
371 pub end: Option<chrono::DateTime<Utc>>,
372 pub role: Option<String>,
373}
374
375#[derive(Clone, Debug, Deserialize)]
376#[serde(rename_all = "camelCase")]
377pub struct EmbedElementFields {
378 pub html: Option<String>,
379 pub safe_embed_code: Option<bool>,
380 pub alt: Option<String>,
381 pub is_mandatory: Option<bool>,
382 pub role: Option<String>,
383 pub source: Option<String>,
384 pub source_domain: Option<String>,
385 pub caption: Option<String>,
386}
387
388#[derive(Clone, Debug, Deserialize)]
389#[serde(rename_all = "camelCase")]
390pub struct InstagramElementFields {
391 pub original_url: String,
392 pub title: String,
393 pub source: String,
394 pub author_url: String,
395 pub author_username: String,
396 pub html: Option<String>,
397 pub width: Option<i32>,
398 pub alt: Option<String>,
399 pub caption: Option<String>,
400 pub role: Option<String>,
401 pub source_domain: Option<String>,
402}
403
404#[derive(Clone, Debug, Deserialize)]
405#[serde(rename_all = "camelCase")]
406pub struct CommentElementFields {
407 pub source: Option<String>,
408 pub discussion_key: Option<String>,
409 pub comment_url: Option<String>,
410 pub original_url: Option<String>,
411 pub source_url: Option<String>,
412 pub discussion_url: Option<String>,
413 pub author_url: Option<String>,
414 pub html: Option<String>,
415 pub author_name: Option<String>,
416 pub comment_id: Option<i32>,
417 pub role: Option<String>,
418}
419
420#[derive(Clone, Debug, Deserialize)]
421#[serde(rename_all = "camelCase")]
422pub struct VineElementFields {
423 pub original_url: String,
424 pub title: String,
425 pub source: String,
426 pub author_url: String,
427 pub author_username: String,
428 pub html: Option<String>,
429 pub width: Option<i32>,
430 pub height: Option<i32>,
431 pub alt: Option<String>,
432 pub caption: Option<String>,
433 pub role: Option<String>,
434 pub source_domain: Option<String>,
435}
436
437#[derive(Clone, Debug, Deserialize)]
438#[serde(rename_all = "camelCase")]
439pub struct ContentAtomElementFields {
440 pub atom_id: String,
441 pub atom_type: String,
442 pub role: Option<String>,
443}
444
445#[derive(Clone, Debug, Deserialize)]
446#[serde(rename_all = "camelCase")]
447pub struct EmbedTracking {
448 pub tracks: String,
449}
450
451#[derive(Clone, Debug, Deserialize)]
452#[serde(rename_all = "camelCase")]
453pub struct CodeElementFields {
454 pub html: String,
455 pub language: String,
456}
457
458#[derive(Clone, Debug, Deserialize)]
459#[serde(rename_all = "camelCase")]
460pub struct Asset {
461 pub r#type: String,
462 pub mime_type: Option<String>,
463 pub file: Option<String>,
464 pub type_data: Option<AssetFields>,
465}
466
467#[derive(Clone, Debug, Deserialize)]
468#[serde(rename_all = "camelCase")]
469pub struct AssetFields {
470 pub aspect_ratio: Option<String>,
471 pub alt_text: Option<String>,
472 pub is_inappropriate_for_adverts: Option<bool>,
473 pub caption: Option<String>,
474 pub credit: Option<String>,
475 pub embeddable: Option<bool>,
476 pub photographer: Option<String>,
477 pub source: Option<String>,
478 pub still_image_url: Option<String>,
479 pub width: Option<i32>,
480 pub height: Option<i32>,
481 pub name: Option<String>,
482 pub secure_file: Option<String>,
483 pub is_master: Option<bool>,
484 pub size_in_bytes: Option<i64>,
485 pub duration_minutes: Option<i32>,
486 pub duration_seconds: Option<i32>,
487 pub display_credit: Option<bool>,
488 pub thumbnail_url: Option<String>,
489 pub role: Option<String>,
490 pub media_id: Option<String>,
491 pub iframe_url: Option<String>,
492 pub script_name: Option<String>,
493 pub script_url: Option<String>,
494 pub block_ads: Option<bool>,
495 pub html: Option<String>,
496 pub embed_type: Option<String>,
497 pub explicit: Option<bool>,
498 pub clean: Option<bool>,
499 pub thumbnail_image_url: Option<String>,
500 pub link_text: Option<String>,
501 pub link_prefix: Option<String>,
502 pub short_url: Option<String>,
503 pub image_type: Option<String>,
504 pub suppliers_reference: Option<String>,
505 pub media_api_uri: Option<String>,
506 pub copyright: Option<String>,
507 pub mime_type: Option<String>,
508 pub url: Option<String>,
509 pub original_url: Option<String>,
510 pub id: Option<String>,
511 pub attribution: Option<String>,
512 pub description: Option<String>,
513 pub title: Option<String>,
514 pub content_auth_system: Option<String>,
515 pub alt: Option<String>,
516 pub picdar_urn: Option<String>,
517 pub comment: Option<String>,
518 pub witness_embed_type: Option<String>,
519 pub author_name: Option<String>,
520 pub author_username: Option<String>,
521 pub author_witness_profile_url: Option<String>,
522 pub author_guardian_profile_url: Option<String>,
523 pub api_url: Option<String>,
524 pub date_created: Option<serde_json::Value>,
525 pub youtube_url: Option<String>,
526 pub youtube_source: Option<String>,
527 pub youtube_title: Option<String>,
528 pub youtube_description: Option<String>,
529 pub youtube_author_name: Option<String>,
530 pub youtube_html: Option<String>,
531 pub venue: Option<String>,
532 pub location: Option<String>,
533 pub identifier: Option<String>,
534 pub price: Option<String>,
535 pub start: Option<chrono::DateTime<Utc>>,
536 pub end: Option<chrono::DateTime<Utc>>,
537 pub safe_embed_code: Option<bool>,
538}
539
540#[derive(Clone, Debug, Deserialize)]
541#[serde(rename_all = "camelCase")]
542pub struct CapiDateTime {
543 pub date_time: i64,
544 pub iso8601: String,
545}
546
547#[derive(Clone, Debug, Deserialize)]
548#[serde(rename_all = "camelCase")]
549#[allow(dead_code)]
550pub struct BlockAttributes {
551 key_event: Option<bool>,
552 summary: Option<bool>,
553 title: Option<String>,
554 pinned: Option<bool>,
555 membership_placeholder: Option<MembershipPlaceholder>,
556}
557
558#[derive(Clone, Debug, Deserialize)]
559#[serde(rename_all = "camelCase")]
560pub struct MembershipPlaceholder {
561 pub campaign_code: Option<String>,
562}
563
564#[derive(Clone, Debug, Deserialize)]
565#[serde(rename_all = "camelCase")]
566#[allow(dead_code)]
567pub struct User {
568 email: Option<String>,
569 first_name: Option<String>,
570 last_name: Option<String>,
571}
572
573#[derive(Clone, Debug, Deserialize)]
574#[serde(rename_all = "camelCase")]
575pub struct Content {
576 pub id: String,
577 pub r#type: String,
578 pub section_id: Option<String>,
579 pub section_name: Option<String>,
580 pub web_publication_date: Option<chrono::DateTime<Utc>>,
581 pub web_title: String,
582 pub web_url: String,
583 pub api_url: String,
584 pub fields: Option<ContentFields>,
585 pub tags: Vec<Tag>,
586 pub references: Option<Vec<Reference>>,
588 pub is_expired: Option<bool>,
589 pub blocks: Option<Blocks>,
590 pub section: Option<Section>,
592 pub is_gone: Option<bool>,
593 pub is_hosted: bool,
594 pub pillar_id: Option<String>,
595 pub pillar_name: Option<String>,
596}
597
598#[derive(Clone, Debug, Deserialize)]
599#[serde(rename_all = "camelCase")]
600pub struct ContentFields {
601 pub headline: Option<String>,
602 pub standfirst: Option<String>,
603 pub trail_text: Option<String>,
604 pub byline: Option<String>,
605 pub main: Option<String>,
606 pub body: Option<String>,
607 pub newspaper_page_number: Option<i32>,
608 pub star_rating: Option<i32>,
609 pub contributor_bio: Option<String>,
610 pub membership_access: Option<String>,
611 pub wordcount: Option<i32>,
612 pub comment_close_date: Option<CapiDateTime>,
613 pub commentable: Option<bool>,
614 pub display_hint: Option<String>,
615 pub first_publication_date: Option<CapiDateTime>,
616 pub has_story_package: Option<bool>,
617 pub is_inappropriate_for_sponsorship: Option<bool>,
618 pub is_premoderated: Option<bool>,
619 pub last_modified: Option<CapiDateTime>,
620 pub live_blogging_now: Option<bool>,
621 pub newspaper_edition_date: Option<CapiDateTime>,
622 pub production_office: Option<String>,
623 pub publication: Option<String>,
624 pub scheduled_publication_date: Option<CapiDateTime>,
625 pub short_url: Option<String>,
626 pub should_hide_adverts: Option<bool>,
627 pub show_in_related_content: Option<bool>,
628 pub thumbnail: Option<String>,
629 pub legally_sensitive: Option<bool>,
630 pub allow_ugc: Option<bool>,
631 pub sensitive: Option<bool>,
632 pub lang: Option<String>,
633 pub is_live: Option<bool>,
634 pub internal_short_id: Option<String>,
635 pub short_social_share_text: Option<String>,
636 pub social_share_text: Option<String>,
637 pub body_text: Option<String>,
638 pub char_count: Option<i32>,
639 pub internal_video_code: Option<String>,
640 pub should_hide_reader_revenue: Option<bool>,
641 pub show_affiliate_links: Option<bool>,
642 pub byline_html: Option<String>,
643}