cskk/dictionary/
static_dict.rs

1use crate::dictionary::file_dictionary::{load_dictionary, DictionaryEntries, FileDictionary};
2use crate::dictionary::lru_ordered_map::LruOrderedMap;
3use crate::dictionary::{CompositeKey, DictEntry, Dictionary};
4use crate::CskkError;
5
6#[derive(Debug)]
7pub(crate) struct StaticFileDict {
8    file_path: String,
9    encode: String,
10    // Midashi -> DictEntry map
11    okuri_ari_dictionary: LruOrderedMap<String, DictEntry>,
12    okuri_nashi_dictionary: LruOrderedMap<String, DictEntry>,
13}
14
15impl StaticFileDict {
16    /// file_path: string
17    /// encode: label of encoding that encoding_rs can recognize. "utf-8", "euc-jp", "cp866" etc.
18    pub(crate) fn new(file_path: &str, encode: &str) -> Result<Self, CskkError> {
19        let dictionary = load_dictionary(file_path, encode.as_bytes())?;
20
21        Ok(StaticFileDict {
22            file_path: String::from(file_path),
23            encode: encode.to_string(),
24            okuri_ari_dictionary: dictionary.okuri_ari,
25            okuri_nashi_dictionary: dictionary.okuri_nashi,
26        })
27    }
28}
29
30impl Dictionary for StaticFileDict {
31    // filedictで共通になってしまったのでuser_dictionaryと共通化する?
32    /// 合致するDictEntryがあれば返す。lookupのみで、選択による副作用なし。
33    fn lookup(&self, composite_key: &CompositeKey) -> Option<&DictEntry> {
34        return if composite_key.has_okuri() {
35            self.okuri_ari_dictionary
36                .peek(&composite_key.get_dict_key())
37        } else {
38            self.okuri_nashi_dictionary
39                .peek(&composite_key.get_dict_key())
40        };
41    }
42
43    fn complete<'a>(
44        &'a self,
45        midashi_head: &'a CompositeKey,
46    ) -> Box<dyn Iterator<Item = &'a DictEntry> + 'a> {
47        FileDictionary::complete(self, midashi_head)
48    }
49
50    fn reload(&mut self) -> Result<(), CskkError> {
51        FileDictionary::reload(self)
52    }
53}
54
55impl FileDictionary for StaticFileDict {
56    fn file_path(&self) -> &str {
57        &self.file_path
58    }
59
60    fn encode(&self) -> &str {
61        &self.encode
62    }
63
64    fn set_dictionary(&mut self, dictionary: DictionaryEntries) {
65        self.okuri_ari_dictionary = dictionary.okuri_ari;
66        self.okuri_nashi_dictionary = dictionary.okuri_nashi;
67    }
68
69    fn get_okuri_nashi_dictionary(&self) -> &LruOrderedMap<String, DictEntry> {
70        &self.okuri_nashi_dictionary
71    }
72
73    fn get_okuri_ari_dictionary(&self) -> &LruOrderedMap<String, DictEntry> {
74        &self.okuri_ari_dictionary
75    }
76}
77
78#[cfg(test)]
79mod test {
80    use super::*;
81
82    #[test]
83    pub fn complete() -> Result<(), CskkError> {
84        let filename = "tests/data/dictionaries/dictionary_complete.dict";
85        let static_dict = StaticFileDict::new(filename, "utf-8")?;
86        let composite_key = CompositeKey::new("", None);
87        //let empty_complete_result = static_dict.complete(&CompositeKey::new("", None)).unwrap();
88        let empty_complete_result = FileDictionary::complete(&static_dict, &composite_key);
89        for (idx, entry) in empty_complete_result.into_iter().enumerate() {
90            match idx {
91                0 => {
92                    assert_eq!("あ", entry.midashi)
93                }
94                1 => {
95                    assert_eq!("い", entry.midashi)
96                }
97                2 => {
98                    assert_eq!("いあ", entry.midashi)
99                }
100                3 => {
101                    assert_eq!("いい", entry.midashi)
102                }
103                _ => {
104                    panic!("Unexpected size of result");
105                }
106            }
107        }
108        let composite_key = CompositeKey::new("い", None);
109        let result = FileDictionary::complete(&static_dict, &composite_key);
110        for (idx, entry) in result.into_iter().enumerate() {
111            match idx {
112                0 => {
113                    assert_eq!("い", entry.midashi)
114                }
115                1 => {
116                    assert_eq!("いあ", entry.midashi)
117                }
118                2 => {
119                    assert_eq!("いい", entry.midashi)
120                }
121                _ => {
122                    panic!("Unexpected size of result");
123                }
124            }
125        }
126        Ok(())
127    }
128}