A3S Docs
A3S Search

Engines

9 built-in search engines and the Engine trait for custom implementations

Engines

A3S Search ships with 9 built-in engines and an Engine trait for adding custom search sources.

Engine Trait

Every search engine implements this trait:

#[async_trait]
pub trait Engine: Send + Sync {
    fn config(&self) -> &EngineConfig;
    async fn search(&self, query: &SearchQuery) -> Result<Vec<SearchResult>>;

    // Default implementations derived from config:
    fn name(&self) -> &str { &self.config().name }
    fn shortcut(&self) -> &str { &self.config().shortcut }
    fn weight(&self) -> f64 { self.config().weight }
    fn is_enabled(&self) -> bool { self.config().enabled }
}

EngineConfig

Prop

Type

Built-in Engines

DuckDuckGo

Privacy-focused search via HTML scraping. No API key required.

use a3s_search::engines::DuckDuckGo;
search.add_engine(DuckDuckGo::new());

Prop

Type

Independent search index. HTML scraping, no API key required.

use a3s_search::engines::Brave;
search.add_engine(Brave::new());

Prop

Type

Bing

Bing International via HTML scraping with query parameter extraction.

use a3s_search::engines::Bing;
search.add_engine(Bing::new());

Prop

Type

Wikipedia

MediaWiki JSON API. Higher weight due to authoritative content. Supports multi-language.

use a3s_search::engines::Wikipedia;

// Default (English)
search.add_engine(Wikipedia::new());

// Chinese Wikipedia
search.add_engine(Wikipedia::with_language("zh"));

Prop

Type

Sogou

Chinese search engine (搜狗搜索).

use a3s_search::engines::Sogou;
search.add_engine(Sogou::new());

Prop

Type

Chinese search engine (360搜索).

use a3s_search::engines::So360;
search.add_engine(So360::new());

Prop

Type

Google (headless)

Google Search via headless Chrome. Higher weight (1.5) due to result quality.

#[cfg(feature = "headless")]
use a3s_search::engines::Google;
search.add_engine(Google::new(fetcher));

Prop

Type

Baidu (headless)

Chinese search engine (百度搜索) via headless Chrome.

#[cfg(feature = "headless")]
use a3s_search::engines::Baidu;
search.add_engine(Baidu::new(fetcher));

Prop

Type

Bing China (headless)

Chinese Bing (必应中国) via headless Chrome.

#[cfg(feature = "headless")]
use a3s_search::engines::BingChina;
search.add_engine(BingChina::new(fetcher));

Prop

Type

Engine Shortcuts

Prop

Type

Custom Engine

Implement the Engine trait to add any search source:

use a3s_search::*;
use async_trait::async_trait;

struct MyApiEngine {
    config: EngineConfig,
    api_key: String,
}

impl MyApiEngine {
    fn new(api_key: String) -> Self {
        Self {
            config: EngineConfig {
                name: "My API".into(),
                shortcut: "myapi".into(),
                categories: vec![EngineCategory::General],
                weight: 1.0,
                timeout: 5,
                enabled: true,
                paging: true,
                safesearch: false,
            },
            api_key,
        }
    }
}

#[async_trait]
impl Engine for MyApiEngine {
    fn config(&self) -> &EngineConfig { &self.config }

    async fn search(&self, query: &SearchQuery) -> Result<Vec<SearchResult>> {
        let client = reqwest::Client::new();
        let resp: serde_json::Value = client
            .get("https://api.example.com/search")
            .query(&[("q", &query.query), ("key", &self.api_key)])
            .send().await.map_err(SearchError::Http)?
            .json().await.map_err(SearchError::Http)?;

        let mut results = vec![];
        if let Some(items) = resp["items"].as_array() {
            for (i, item) in items.iter().enumerate() {
                results.push(
                    SearchResult::new(
                        item["url"].as_str().unwrap_or_default(),
                        item["title"].as_str().unwrap_or_default(),
                        item["snippet"].as_str().unwrap_or_default(),
                    )
                    .with_engine("myapi", (i + 1) as u32)
                );
            }
        }
        Ok(results)
    }
}

Custom Engine Weight

Override the default weight for any built-in engine:

use a3s_search::{EngineConfig, engines::Wikipedia};

let wiki = Wikipedia::new().with_config(EngineConfig {
    name: "Wikipedia".to_string(),
    shortcut: "wiki".to_string(),
    weight: 1.5,
    ..Default::default()
});
search.add_engine(wiki);

On this page