Skip to main content

headless_engine/google/
types.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Serialize, Deserialize, Clone, Default)]
4pub struct GoogleSearchResult {
5    pub query: String,
6    pub title: String,
7    pub ai_overview: Option<String>,
8    pub knowledge_panel: Option<String>,
9    pub organic_results: Vec<OrganicResult>,
10    pub related_questions: Vec<String>,
11}
12
13#[derive(Debug, Serialize, Deserialize, Clone, Default)]
14pub struct OrganicResult {
15    pub title: String,
16    pub link: String,
17    pub snippet: String,
18}
19
20impl GoogleSearchResult {
21    pub fn to_markdown(&self) -> String {
22        let mut md = format!("# {} - Google Search\n\n", self.title);
23        if let Some(ai) = &self.ai_overview {
24            md.push_str("## ✨ AI Overview\n");
25            md.push_str(ai);
26            md.push_str("\n\n");
27        }
28        if let Some(kp) = &self.knowledge_panel {
29            md.push_str("## 🧠 Knowledge Panel\n");
30            md.push_str(kp);
31            md.push_str("\n\n");
32        }
33        if !self.organic_results.is_empty() {
34            md.push_str("## 🔍 Organic Results\n\n");
35            for (i, res) in self.organic_results.iter().enumerate() {
36                md.push_str(&format!(
37                    "### {}. [{}]({})\n{}\n\n",
38                    i + 1,
39                    res.title,
40                    res.link,
41                    res.snippet
42                ));
43            }
44        }
45        if !self.related_questions.is_empty() {
46            md.push_str("## ❓ People Also Ask\n");
47            for q in &self.related_questions {
48                md.push_str(&format!("- {}\n", q));
49            }
50        }
51        md
52    }
53}
54
55// Minimal implementations for the other 30 capabilities
56// Since there are 31 methods, we will define a generalized struct for the ones we don't have full extractors for yet.
57#[derive(Debug, Serialize, Deserialize, Clone, Default)]
58pub struct GenericGoogleResult {
59    pub query: String,
60    pub title: String,
61    pub raw_markdown: String,
62}
63
64impl GenericGoogleResult {
65    pub fn to_markdown(&self) -> String {
66        self.raw_markdown.clone()
67    }
68}
69
70#[derive(Debug, Serialize, Deserialize, Clone, Default)]
71pub struct GoogleAutocompleteResult {
72    pub query: String,
73    pub suggestions: Vec<String>,
74}
75
76impl GoogleAutocompleteResult {
77    pub fn to_markdown(&self) -> String {
78        let mut md = format!("# Autocomplete for '{}'\n\n", self.query);
79        for s in &self.suggestions {
80            md.push_str(&format!("- {}\n", s));
81        }
82        md
83    }
84}
85
86// You can expand these structs as specific parsers are added.