1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4pub struct HtmlPage {
5 pub url_or_path: String,
6 pub source: String,
7 pub title: Option<String>,
8 pub meta_description: Option<String>,
9 pub canonical_urls: Vec<String>,
10 pub language: Option<String>,
11 pub headings: Vec<Heading>,
12 pub links: Vec<LinkInfo>,
13 pub images: Vec<ImageInfo>,
14 pub open_graph: OpenGraphTags,
15 pub twitter_card: TwitterCardTags,
16 pub json_ld_blocks: Vec<JsonLdBlock>,
17 pub main_text: String,
18 pub has_main_landmark: bool,
19 pub forms: Vec<FormInfo>,
20 pub breadcrumbs_detected: bool,
21}
22
23#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
24pub struct Heading {
25 pub level: u8,
26 pub text: String,
27}
28
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
30pub struct LinkInfo {
31 pub href: String,
32 pub text: String,
33 pub is_internal: bool,
34}
35
36#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
37pub struct ImageInfo {
38 pub src: String,
39 pub alt: Option<String>,
40 pub width: Option<String>,
41 pub height: Option<String>,
42 pub has_caption: bool,
43}
44
45#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
46pub struct OpenGraphTags {
47 pub title: Option<String>,
48 pub description: Option<String>,
49 pub image: Option<String>,
50 pub url: Option<String>,
51 pub type_: Option<String>,
52}
53
54#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
55pub struct TwitterCardTags {
56 pub card: Option<String>,
57 pub title: Option<String>,
58 pub description: Option<String>,
59 pub image: Option<String>,
60}
61
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
63pub struct JsonLdBlock {
64 pub raw: String,
65 pub valid_json: bool,
66 pub types: Vec<String>,
67}
68
69#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
70pub struct FormInfo {
71 pub id: Option<String>,
72 pub inputs_without_label: Vec<String>,
73}
74
75impl HtmlPage {
76 pub fn display_name(&self) -> &str {
77 self.title
78 .as_deref()
79 .filter(|t| !t.is_empty())
80 .unwrap_or(&self.url_or_path)
81 }
82}