1#![warn(missing_docs)]
22#![deny(unsafe_code)]
23#![cfg_attr(feature = "simd", feature(portable_simd))]
24#![allow(
25 clippy::inline_always,
26 clippy::similar_names,
27 clippy::cast_precision_loss,
28 clippy::cast_possible_truncation,
29 clippy::option_if_let_else,
30 clippy::map_unwrap_or,
31 clippy::zero_sized_map_values,
32 clippy::missing_panics_doc,
33 clippy::unwrap_used
34)]
35
36pub mod dictionary;
37pub mod domain;
38pub mod entry_store;
39pub mod file_watcher;
40pub mod hot_reload;
41pub mod lazy_entries;
42pub mod lazy_entries_v3;
43pub mod loader;
44pub mod matrix;
45pub mod string_pool;
46pub mod trie;
47pub mod user_dict;
48
49#[cfg(feature = "hot-reload-v2")]
50pub mod hot_reload_v2;
51
52pub use dictionary::{DictEntry, DictionaryLoader, LoadOptions, SystemDictionary};
53pub use entry_store::{EagerStore, EntryStore, LazyStore};
54pub use error::{DictError, Result};
55pub use file_watcher::{FileEvent, FileWatcher, WatchConfig};
56pub use hot_reload::{
57 DeltaUpdate, DeltaUpdateBuilder, EntryChange, HotReloadDictionary, Version, VersionInfo,
58};
59pub use lazy_entries::LazyEntries;
60pub use loader::{LazyDictionary, LoaderConfig, MmapDictionary};
61pub use matrix::{ConnectionMatrix, DenseMatrix, Matrix, MatrixLoader, MmapMatrix, SparseMatrix};
62pub use string_pool::{ConcurrentStringPool, StringPool, StringPoolStats};
63pub use trie::{MmapTrie, PrefixSearchResult, Trie, TrieBackend, TrieBuilder};
64pub use user_dict::{UserDictionary, UserDictionaryBuilder, UserEntry};
65
66#[derive(Debug, Clone, PartialEq, Eq)]
68pub struct Entry {
69 pub surface: String,
71 pub left_id: u16,
73 pub right_id: u16,
75 pub cost: i16,
77 pub feature: String,
79}
80
81pub trait Dictionary {
83 fn lookup(&self, surface: &str) -> Vec<Entry>;
85
86 fn get_connection_cost(&self, left_id: u16, right_id: u16) -> i16;
88}
89
90pub mod error {
92 use thiserror::Error;
93
94 #[derive(Error, Debug)]
96 pub enum DictError {
97 #[error("IO error: {0}")]
99 Io(#[from] std::io::Error),
100
101 #[error("Invalid dictionary format: {0}")]
103 Format(String),
104
105 #[error("Version mismatch: expected {expected}, found {found}")]
107 Version {
108 expected: u32,
110 found: u32,
112 },
113 }
114
115 pub type Result<T> = std::result::Result<T, DictError>;
117}
118
119pub mod format {
123
124 pub struct Header {
126 pub magic: [u8; 4],
128 pub version: u32,
130 pub entry_count: u32,
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[test]
140 fn test_entry_creation() {
141 let entry = Entry {
142 surface: "안녕".to_string(),
143 left_id: 1,
144 right_id: 1,
145 cost: 100,
146 feature: "NNG,*,T,안녕,*,*,*,*".to_string(),
147 };
148
149 assert_eq!(entry.surface, "안녕");
150 }
151}