1#[macro_use]
2extern crate lazy_static;
3
4use std::cmp::Reverse;
5use std::collections::HashSet;
6use std::error::Error;
7use tinysearch_shared::{Filters, Score, Storage, PostId};
8use wasm_bindgen::prelude::*;
9
10#[global_allocator]
11static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
12
13fn load_filters() -> Result<Filters, Box<Error>> {
14 let bytes = include_bytes!("../storage");
15 Ok(Storage::from_bytes(bytes)?.filters)
16}
17
18lazy_static! {
19 static ref FILTERS: Filters = load_filters().unwrap();
20}
21
22#[wasm_bindgen]
23pub fn search(query: String, num_results: usize) -> JsValue {
24 let search_terms: HashSet<String> =
25 query.split_whitespace().map(|s| s.to_lowercase()).collect();
26
27 let mut matches: Vec<(&PostId, u32)> = FILTERS
28 .iter()
29 .map(|(name, filter)| (name, filter.score(&search_terms)))
30 .filter(|(_, score)| *score > 0)
31 .collect();
32
33 matches.sort_by_key(|k| Reverse(k.1));
34
35 let results: Vec<&PostId> = matches
36 .iter()
37 .map(|(name, _)| name.to_owned())
38 .take(num_results)
39 .collect();
40
41 JsValue::from_serde(&results).unwrap()
42}