File size: 1,326 Bytes
3d2a871 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | use anyhow::Result;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct DdgResult {
#[serde(rename = "Text")]
text: Option<String>,
#[serde(rename = "FirstURL")]
first_url: Option<String>,
}
#[derive(Deserialize, Debug)]
struct DdgResponse {
#[serde(rename = "AbstractText")]
abstract_text: Option<String>,
#[serde(rename = "RelatedTopics")]
related_topics: Vec<DdgResult>,
}
pub async fn search(client: &reqwest::Client, query: &str) -> Result<String> {
let url = format!(
"https://api.duckduckgo.com/?q={}&format=json&no_html=1&skip_disambig=1",
urlencoding::encode(query)
);
let resp = client
.get(&url)
.header("User-Agent", "sovereign-35/1.0")
.send()
.await?
.json::<DdgResponse>()
.await?;
let mut out = String::new();
if let Some(abs) = &resp.abstract_text {
if !abs.is_empty() {
out.push_str(&format!("DDG ABSTRACT: {}\n\n", abs));
}
}
for (i, r) in resp.related_topics.iter().take(3).enumerate() {
if let (Some(text), Some(url)) = (&r.text, &r.first_url) {
out.push_str(&format!("[DDG {}] {}\n{}\n\n", i + 1, text, url));
}
}
if out.is_empty() {
out = "DDG: no results".to_string();
}
Ok(out)
}
|