rink_core/commands/
search.rs1use crate::{
6 loader::Context,
7 output::{NumberParts, SearchReply},
8 types::{BaseUnit, Dimensionality},
9};
10
11pub(crate) fn search_internal<'a>(
12 ctx: &'a Context,
13 query: &str,
14 num_results: usize,
15) -> Vec<&'a str> {
16 let base_units = ctx.registry.base_units.iter().map(|dim| &dim.id[..]);
17 let units = ctx.registry.units.keys().map(|name| &name[..]);
18 let substances = ctx.registry.substances.keys().map(|name| &name[..]);
19
20 let iter = base_units.chain(units).chain(substances);
21 crate::algorithms::search_impl(iter, query, num_results)
22}
23
24pub fn search(ctx: &Context, query: &str, num_results: usize) -> SearchReply {
25 SearchReply {
26 results: search_internal(ctx, query, num_results)
27 .into_iter()
28 .map(|name| {
29 let parts = ctx
30 .lookup(name)
31 .map(|x| x.to_parts(ctx))
32 .or_else(|| {
33 if ctx.registry.substances.get(name).is_some() {
34 Some(NumberParts {
35 quantity: Some("substance".to_owned()),
36 ..Default::default()
37 })
38 } else {
39 None
40 }
41 })
42 .expect("Search returned non-existent result");
43 let raw = Dimensionality::base_unit(BaseUnit::new(name));
44 NumberParts {
45 unit: Some(name.to_owned()),
46 raw_unit: Some(raw),
47 quantity: parts.quantity,
48 ..Default::default()
49 }
50 })
51 .collect(),
52 }
53}