//! These types are not used for generating `Index`es. They are provided to help with //! creating compatible JSON structures for configuring the JavaScript search //! function. //! //! *Reference:* //! use std::collections::BTreeMap; /// Used to set the search configuration for a specific field. /// When `expand` or `bool` is `None`, elasticlunr.js will use the value from /// the global configuration. The `boost` field, if present, /// increases the importance of this field when ordering search results. #[derive(Serialize, Deserialize, Default, Debug, Copy, Clone, Eq, PartialEq)] pub struct SearchOptionsField { #[serde(skip_serializing_if = "Option::is_none")] pub boost: Option, #[serde(skip_serializing_if = "Option::is_none")] pub bool: Option, #[serde(skip_serializing_if = "Option::is_none")] pub expand: Option, } /// Sets which boolean model is used for searching with /// multiple terms. Defaults to `Or`. /// /// - *AND* requires every search term to be present in results /// - *OR* accepts results which have at least one term /// #[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum SearchBool { Or, And, } impl Default for SearchBool { fn default() -> Self { SearchBool::Or } } /// The search configuration map which is passed to the /// elasticlunr.js `Index.search()` function. /// /// |Key |Default| /// |--------|-------| /// |`bool` |`OR` | /// |`expand`|`false`| #[derive(Serialize, Deserialize, Default, Debug, Clone, Eq, PartialEq)] pub struct SearchOptions { pub bool: SearchBool, pub expand: bool, pub fields: BTreeMap, } #[cfg(test)] mod tests { use super::*; use serde_json; #[test] fn test_normal_config() { let options = SearchOptions { fields: btreemap![ "title".into() => SearchOptionsField { boost: Some(5), ..Default::default() }, "body".into() => SearchOptionsField { boost: Some(1), ..Default::default() }, ], ..Default::default() }; let stringed = serde_json::to_string(&options).unwrap(); assert_eq!( stringed, r#"{"bool":"OR","expand":false,"fields":{"body":{"boost":1},"title":{"boost":5}}}"# ); } #[test] fn test_complex_config() { let options = SearchOptions { fields: btreemap! { "title".into() => SearchOptionsField { expand: Some(true), ..Default::default() }, "body".into() => SearchOptionsField { bool: Some(SearchBool::Or), ..Default::default() }, "breadcrumbs".into() => SearchOptionsField { bool: Some(SearchBool::default()), boost: Some(200), ..Default::default() }, }, expand: false, bool: SearchBool::And, }; let stringed = serde_json::to_string_pretty(&options).unwrap(); assert_eq!( stringed, r#"{ "bool": "AND", "expand": false, "fields": { "body": { "bool": "OR" }, "breadcrumbs": { "boost": 200, "bool": "OR" }, "title": { "expand": true } } }"# ); } }