Skip to main content

lindera_dictionary/
macros.rs

1//! Shared macros for the per-dictionary crates (`lindera-ipadic`,
2//! `lindera-ko-dic`, `lindera-unidic`, `lindera-cc-cedict`, `lindera-jieba`,
3//! `lindera-ipadic-neologd`).
4//!
5//! Each of those crates' `embedded` module used to contain ~90 lines of
6//! identical boilerplate that differed only in the dictionary subdirectory
7//! name and the loader struct name. [`embedded_dictionary!`] generates that
8//! boilerplate from those two inputs.
9
10/// Generates the embedded-dictionary loader for a dictionary crate.
11///
12/// The dictionary data is baked into the binary with `include_bytes!`,
13/// reading from the `LINDERA_WORKDIR` directory populated by the crate's
14/// build script.
15///
16/// * `$dir` — the dictionary subdirectory inside `LINDERA_WORKDIR`
17///   (e.g. `"/lindera-ipadic"`).
18/// * `$loader` — the public loader struct name (e.g. `EmbeddedIPADICLoader`).
19///
20/// # Example
21///
22/// ```ignore
23/// lindera_dictionary::embedded_dictionary!("/lindera-ipadic", EmbeddedIPADICLoader);
24/// ```
25#[macro_export]
26macro_rules! embedded_dictionary {
27    ($dir:literal, $loader:ident) => {
28        const CHAR_DEFINITION_DATA: &[u8] =
29            include_bytes!(concat!(env!("LINDERA_WORKDIR"), $dir, "/char_def.bin"));
30        const CONNECTION_DATA: &[u8] =
31            include_bytes!(concat!(env!("LINDERA_WORKDIR"), $dir, "/matrix.mtx"));
32        const DA_DATA: &[u8] = include_bytes!(concat!(env!("LINDERA_WORKDIR"), $dir, "/dict.da"));
33        const VALS_DATA: &[u8] =
34            include_bytes!(concat!(env!("LINDERA_WORKDIR"), $dir, "/dict.vals"));
35        const UNKNOWN_DATA: &[u8] =
36            include_bytes!(concat!(env!("LINDERA_WORKDIR"), $dir, "/unk.bin"));
37        const WORDS_IDX_DATA: &[u8] =
38            include_bytes!(concat!(env!("LINDERA_WORKDIR"), $dir, "/dict.wordsidx"));
39        const WORDS_DATA: &[u8] =
40            include_bytes!(concat!(env!("LINDERA_WORKDIR"), $dir, "/dict.words"));
41        const METADATA_DATA: &[u8] =
42            include_bytes!(concat!(env!("LINDERA_WORKDIR"), $dir, "/metadata.json"));
43
44        /// Loads the embedded dictionary from data baked into the binary.
45        pub fn load() -> $crate::LinderaResult<$crate::dictionary::Dictionary> {
46            let metadata = $crate::dictionary::metadata::Metadata::load(METADATA_DATA)?;
47            let prefix_dictionary = $crate::dictionary::prefix_dictionary::PrefixDictionary::load(
48                DA_DATA,
49                VALS_DATA,
50                WORDS_IDX_DATA,
51                WORDS_DATA,
52                true,
53                $crate::dictionary::prefix_dictionary::DaTrust::Trusted,
54            )?;
55            let connection_cost_matrix =
56                $crate::dictionary::connection_cost_matrix::ConnectionCostMatrix::load(
57                    CONNECTION_DATA,
58                )?;
59            let character_definition =
60                $crate::dictionary::character_definition::CharacterDefinition::load(
61                    CHAR_DEFINITION_DATA,
62                )?;
63            let unknown_dictionary =
64                $crate::dictionary::unknown_dictionary::UnknownDictionary::load(UNKNOWN_DATA)?;
65
66            Ok($crate::dictionary::Dictionary {
67                prefix_dictionary: ::std::sync::Arc::new(prefix_dictionary),
68                connection_cost_matrix: ::std::sync::Arc::new(connection_cost_matrix),
69                character_definition,
70                unknown_dictionary,
71                metadata,
72            })
73        }
74
75        /// Loader that returns the dictionary embedded in the binary.
76        pub struct $loader;
77
78        impl Default for $loader {
79            fn default() -> Self {
80                Self::new()
81            }
82        }
83
84        impl $loader {
85            pub fn new() -> Self {
86                Self
87            }
88        }
89
90        impl $crate::loader::DictionaryLoader for $loader {
91            fn load(&self) -> $crate::LinderaResult<$crate::dictionary::Dictionary> {
92                load()
93            }
94        }
95    };
96}