1#![doc = include_str!("../README.md")]
2#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
3
4use std::collections::HashMap;
5
6#[cfg(feature = "static")]
7use lazy_static::{lazy_static, initialize};
8
9#[cfg(feature = "static")]
10lazy_static! {
11 static ref DICT: HashMap<String, Vec<String>> = parse_dict();
12}
13
14#[cfg(feature = "static")]
16pub fn init() {
17 initialize(&DICT);
18}
19
20pub fn dict() -> HashMap<String, Vec<String>> {
22 let mut dict: HashMap<String, Vec<String>> = HashMap::new();
23
24 #[cfg(feature = "static")]
25 dict.extend(DICT.to_owned());
26
27 if dict.is_empty() {
29 dict.extend(parse_dict());
30 }
31
32 dict
33}
34
35pub fn synonyms(word: impl AsRef<str>) -> Vec<String> {
37 let mut s = dict()
38 .get(word.as_ref())
39 .map(|x| x.clone())
40 .unwrap_or_default();
41
42 s.dedup();
43 s.sort_by(|a, b| a.cmp(&b));
44
45 s
46}
47
48fn parse_dict() -> HashMap<String, Vec<String>> {
49 let mut dict: HashMap<String, Vec<String>> = HashMap::new();
50
51 #[cfg(feature = "wordnet")]
52 for line in thesaurus_wordnet::uncompress().lines() {
53 parse_dict_line(line, &mut dict);
54 }
55
56 #[cfg(feature = "moby")]
57 for line in thesaurus_moby::uncompress().lines() {
58 parse_dict_line(line, &mut dict);
59 }
60
61 dict
62}
63
64fn parse_dict_line(line: &str, dict: &mut HashMap<String, Vec<String>>) {
65 let mut line: Vec<String> = line.split('|').map(|x| x.to_string().to_lowercase()).collect();
66
67 let name = line.remove(0);
68
69 if let Some(x) = dict.get_mut(&name) {
70 x.extend_from_slice(&line);
71 x.dedup();
72 } else {
73 dict.insert(name, line);
74 }
75}