1use std::path::PathBuf;
14use std::sync::Arc;
15
16use serde::Deserialize;
17
18use crate::util::serde::env_var;
19
20#[derive(Deserialize)]
21pub struct Config {
22 pub normalization: ConfigNormalization,
23
24 pub tokenization: ConfigTokenization,
25
26 pub search: ConfigSearch,
27
28 pub store: ConfigStore,
29}
30
31impl Config {
32 pub fn validate(&self) {
33 if self.store.kv.database.write_buffer == 0 {
35 panic!("write_buffer for kv must not be zero");
36 }
37
38 if self.store.kv.database.flush_after >= self.store.kv.pool.inactive_after {
40 panic!("flush_after for kv must be strictly lower than inactive_after");
41 }
42
43 if self.store.fst.graph.consolidate_after >= self.store.fst.pool.inactive_after {
45 panic!("consolidate_after for fst must be strictly lower than inactive_after");
46 }
47 }
48}
49
50#[derive(Deserialize, Clone, Copy)]
53pub struct ConfigNormalization {
54 pub diacritic_folding_enabled: bool,
55
56 #[cfg(feature = "stemming")]
57 pub stemming_enabled: bool,
58}
59
60#[derive(Deserialize, Clone, Copy)]
62pub struct ConfigTokenization {
63 pub detect_special_patterns: bool,
64
65 #[serde(alias = "split_special_patterns")]
66 pub compat_split_special_patterns: bool,
67}
68
69#[derive(Deserialize)]
70pub struct ConfigSearch {
71 pub query_limit_default: u16,
72
73 pub query_limit_maximum: u16,
74
75 pub query_alternates_try: usize,
76
77 pub suggest_limit_default: u16,
78
79 pub suggest_limit_maximum: u16,
80
81 pub list_limit_default: u16,
82
83 pub list_limit_maximum: u16,
84}
85
86#[derive(Deserialize)]
87pub struct ConfigStore {
88 pub kv: Arc<ConfigStoreKV>,
89
90 pub fst: Arc<ConfigStoreFST>,
91}
92
93#[derive(Deserialize)]
94pub struct ConfigStoreKV {
95 #[serde(deserialize_with = "env_var::path_buf")]
96 pub path: PathBuf,
97
98 pub retain_word_objects: usize,
99
100 pub pool: ConfigStoreKVPool,
101
102 pub database: ConfigStoreKVDatabase,
103}
104
105#[derive(Deserialize)]
106pub struct ConfigStoreKVPool {
107 pub inactive_after: u64,
108}
109
110#[derive(Deserialize)]
111pub struct ConfigStoreKVDatabase {
112 pub flush_after: u64,
113
114 pub compress: bool,
115
116 pub parallelism: u16,
117
118 pub max_files: Option<u32>,
119
120 pub max_compactions: u16,
121
122 pub max_flushes: u16,
123
124 pub write_buffer: usize,
125
126 pub write_ahead_log: bool,
127}
128
129#[derive(Deserialize)]
130pub struct ConfigStoreFST {
131 #[serde(deserialize_with = "env_var::path_buf")]
132 pub path: PathBuf,
133
134 pub pool: ConfigStoreFSTPool,
135
136 pub graph: ConfigStoreFSTGraph,
137}
138
139#[derive(Deserialize)]
140pub struct ConfigStoreFSTPool {
141 pub inactive_after: u64,
142}
143
144#[derive(Deserialize)]
145pub struct ConfigStoreFSTGraph {
146 pub consolidate_after: u64,
147
148 pub max_size: usize,
149
150 pub max_words: usize,
151}
152
153#[cfg(test)]
154pub(crate) mod tests {
155 pub fn defaults_toml() -> &'static str {
156 r#"
157 [channel]
158 inet = "[::1]:1491"
159 tcp_timeout = 300
160
161 [normalization]
162 diacritic_folding_enabled = true
163 stemming_enabled = false
164
165 [tokenization]
166 detect_special_patterns = true
167 compat_split_special_patterns = false
168
169 [search]
170 query_limit_default = 10
171 query_limit_maximum = 100
172 query_alternates_try = 4
173 suggest_limit_default = 5
174 suggest_limit_maximum = 20
175 list_limit_default = 100
176 list_limit_maximum = 500
177
178 [store.kv]
179 path = "./data/store/kv/"
180 retain_word_objects = 1000
181 pool.inactive_after = 1800
182 database.flush_after = 900
183 database.compress = true
184 database.parallelism = 2
185 database.max_compactions = 1
186 database.max_flushes = 1
187 database.write_buffer = 16384
188 database.write_ahead_log = true
189
190 [store.fst]
191 path = "./data/store/fst/"
192 pool.inactive_after = 300
193 graph.consolidate_after = 180
194 graph.max_size = 2048
195 graph.max_words = 250000
196 "#
197 }
198}