search_provider/
lib.rs

1//! The crate aims to provide an easy to use wrapper around the GNOME Shell Search Provider DBus interface.
2//!
3//! - [Writing a Search Provider tutorial](https://developer.gnome.org/documentation/tutorials/search-provider.html)
4//!
5//!
6//! # How to use
7//!
8//! - [Register a new search provider](https://developer.gnome.org/documentation/tutorials/search-provider.html#registering-a-new-search-provider)
9//! - Implement the [`SearchProviderImpl`] trait for the struct that holds your Application.
10//! - Once the application is installed, enable it in GNOME Settings -> Search.
11//!
12//! ```
13//! use search_provider::{ResultID, ResultMeta, SearchProviderImpl};
14//! use std::collections::HashMap;
15//!
16//! #[derive(Debug)]
17//! struct Application {
18//!     results: HashMap<String, String>,
19//! }
20//! impl SearchProviderImpl for Application {
21//!     fn activate_result(&self, identifier: ResultID, terms: &[String], timestamp: u32) {
22//!         let result = self.results.get(&identifier);
23//!         println!(
24//!             "activating result {:#?} identified by {}",
25//!             result, identifier
26//!         );
27//!     }
28//!
29//!     fn initial_result_set(&self, terms: &[String]) -> Vec<ResultID> {
30//!         // Here do your search logic
31//!         if terms.contains(&"some_value".to_owned()) {
32//!             vec!["some_key".to_owned()]
33//!         } else {
34//!             vec![]
35//!         }
36//!     }
37//!
38//!     fn result_metas(&self, identifiers: &[ResultID]) -> Vec<ResultMeta> {
39//!         self.results
40//!             .iter()
41//!             .map(|(identifier, value)| {
42//!                 ResultMeta::builder(identifier.to_owned(), "Some name")
43//!                     .description("Some description of the current identifier")
44//!                     .build()
45//!             })
46//!             .collect::<Vec<_>>()
47//!     }
48//! }
49//! ```
50//!
51//! - Create an instance of [`SearchProvider`]
52//!
53//! ```ignore
54//! use search_provider::SearchProvider;
55//! use std::collections::HashMap;
56//!
57//! async fn main_entry() -> zbus::Result<()> {
58//!     let mut results = HashMap::new();
59//!     results.insert("some_key".to_string(), "some_value".to_string());
60//!     let app = Application { results };
61//!     let provider = SearchProvider::new(
62//!         app,
63//!         "org.gnome.design.IconLibrary.SearchProvider",
64//!         "/org/gnome/design/IconLibrary/SearchProvider",
65//!     )
66//!     .await?;
67//!     Ok(())
68//! }
69//! ```
70
71mod search_provider;
72pub use crate::search_provider::SearchProvider;
73
74mod result_metadata;
75pub use crate::result_metadata::{IconData, ResultMeta, ResultMetaBuilder};
76
77/// A result identifier.
78pub type ResultID = String;
79
80/// A trait to implement to communicate with the search provider
81/// interface.
82pub trait SearchProviderImpl {
83    /// The method is called when a user clicks on an individual search result
84    /// to open it in the application.
85    ///
86    /// # Arguments
87    ///
88    /// * `identifier` - the result ID.
89    /// * `terms` - current search terms.
90    /// * `timestamp` - current timestamp.
91    fn activate_result(&self, identifier: ResultID, terms: &[String], timestamp: u32);
92
93    /// The method is called when a new search is started.
94    ///
95    /// # Arguments
96    ///
97    /// * `terms` - current search terms.
98    /// * `timestamp` - current timestamp.
99    ///
100    /// # Returns
101    ///
102    /// A list of search results IDs. GNOME Shell, will call [`result_metas()`](SearchProviderImpl::result_metas`)
103    /// on some of those IDs to retrieve the corresponding [`ResultMeta`].
104    #[doc(alias = "get_initial_result_set")]
105    fn initial_result_set(&self, terms: &[String]) -> Vec<ResultID>;
106
107    /// The method is called to refine the initial search results when more characters were typed
108    /// in the search entry.
109    ///
110    /// # Arguments
111    ///
112    /// * `previous_results` - list of results ID returned by a previous call to [`initial_result_set()`](SearchProviderImpl::initial_result_set`).
113    /// * `terms` - current search terms.
114    ///
115    /// # Returns
116    ///
117    /// A list of search results IDs. GNOME Shell, will call [`result_metas()`](SearchProviderImpl::result_metas`)
118    /// on some of those IDs to retrieve the corresponding [`ResultMeta`].
119    ///
120    /// By default the method calls [`initial_result_set()`](SearchProviderImpl::initial_result_set`).
121    #[doc(alias = "get_subsearch_result_set")]
122    fn subsearch_result_set(
123        &self,
124        _previous_results: &[ResultID],
125        terms: &[String],
126    ) -> Vec<ResultID> {
127        self.initial_result_set(terms)
128    }
129
130    /// The method is called to obtain detailed information of the results.
131    ///
132    /// # Arguments
133    ///
134    /// * `identifiers` - search result IDs.
135    ///
136    /// # Returns
137    ///
138    /// A list of their corresponding [`ResultMeta`], see [`ResultMeta::builder`] on how to construct one.
139    #[doc(alias = "get_result_metas")]
140    fn result_metas(&self, identifiers: &[ResultID]) -> Vec<ResultMeta>;
141
142    /// The method is called when a user clicks on the provider icon to
143    /// display more search results in the application.
144    ///
145    /// # Arguments
146    ///
147    /// * `terms` - current search terms.
148    /// * `timestamp` - current timestamp.
149    ///
150    /// By default the method does nothing.
151    fn launch_search(&self, _terms: &[String], _timestamp: u32) {}
152}