1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use jpreprocess_core::{error::JPreprocessErrorKind, word_entry::WordEntry, JPreprocessResult};
use lindera_tokenizer::token::Token;

use super::{
    serializer::{jpreprocess::JPreprocessSerializer, lindera::LinderaSerializer},
    DictionaryFetcher, DictionarySerializer, DictionaryStore,
};

pub struct WordDictionaryConfig {
    pub system: Box<dyn DictionarySerializer>,
    pub user: Option<Box<dyn DictionarySerializer>>,
}

impl WordDictionaryConfig {
    pub fn new(system: WordDictionaryMode, user: Option<WordDictionaryMode>) -> Self {
        Self {
            system: system.into_serializer(),
            user: user.map(|user| user.into_serializer() as Box<dyn DictionarySerializer>),
        }
    }
}

impl DictionaryFetcher for WordDictionaryConfig {
    fn get_word(&self, token: &Token) -> JPreprocessResult<WordEntry> {
        if token.word_id.is_unknown() {
            Ok(WordEntry::default())
        } else if token.word_id.is_system() {
            self.system
                .deserialize(token.dictionary.get_bytes(token.word_id.0)?)
        } else if let Some(ref user_dict) = self.user {
            user_dict.deserialize(
                token
                    .user_dictionary
                    .ok_or(
                        JPreprocessErrorKind::WordNotFoundError.with_error(anyhow::anyhow!(
                "The word is flagged as UserDictionary, but Lindera UserDictionary is empty."
            )),
                    )?
                    .get_bytes(token.word_id.0)?,
            )
        } else {
            Err(
                JPreprocessErrorKind::WordNotFoundError.with_error(anyhow::anyhow!(
                    "The word is flagged as UserDictionary, but UserDictionary mode is not set."
                )),
            )
        }
    }
}

#[derive(Clone, Copy, Debug)]
pub enum WordDictionaryMode {
    Lindera,
    JPreprocess,
}

impl WordDictionaryMode {
    pub fn into_serializer(self) -> Box<dyn DictionarySerializer + Send + Sync> {
        match self {
            Self::Lindera => Box::new(LinderaSerializer),
            Self::JPreprocess => Box::new(JPreprocessSerializer),
        }
    }
}