novel_segment/
pipeline.rs1use crate::segment::Segment;
4use crate::word::Word;
5
6pub const URL_TOKENIZER: &str = "URLTokenizer";
7pub const WILDCARD_TOKENIZER: &str = "WildcardTokenizer";
8pub const PUNCTUATION_TOKENIZER: &str = "PunctuationTokenizer";
9pub const FOREIGN_TOKENIZER: &str = "ForeignTokenizer";
10pub const DICT_TOKENIZER: &str = "DictTokenizer";
11pub const CHS_NAME_TOKENIZER: &str = "ChsNameTokenizer";
12pub const JP_SIMPLE_TOKENIZER: &str = "JpSimpleTokenizer";
13pub const ZHUYIN_TOKENIZER: &str = "ZhuyinTokenizer";
14pub const EMAIL_OPTIMIZER: &str = "EmailOptimizer";
15pub const CHS_NAME_OPTIMIZER: &str = "ChsNameOptimizer";
16pub const DICT_OPTIMIZER: &str = "DictOptimizer";
17pub const DATETIME_OPTIMIZER: &str = "DatetimeOptimizer";
18pub const FOREIGN_OPTIMIZER: &str = "ForeignOptimizer";
19pub const ZHT_SYNONYM_OPTIMIZER: &str = "ZhtSynonymOptimizer";
20pub const ADJECTIVE_OPTIMIZER: &str = "AdjectiveOptimizer";
21
22pub fn default_tokenizer_names(all_mod: bool) -> Vec<&'static str> {
23 let _ = all_mod;
24 vec![
25 URL_TOKENIZER,
26 WILDCARD_TOKENIZER,
27 PUNCTUATION_TOKENIZER,
28 FOREIGN_TOKENIZER,
29 DICT_TOKENIZER,
30 CHS_NAME_TOKENIZER,
31 JP_SIMPLE_TOKENIZER,
32 ZHUYIN_TOKENIZER,
33 ]
34}
35
36pub fn default_optimizer_names(all_mod: bool) -> Vec<&'static str> {
37 let mut v = vec![
38 EMAIL_OPTIMIZER,
39 CHS_NAME_OPTIMIZER,
40 DICT_OPTIMIZER,
41 DATETIME_OPTIMIZER,
42 FOREIGN_OPTIMIZER,
43 ADJECTIVE_OPTIMIZER,
44 ];
45 if all_mod {
46 v.insert(v.len() - 1, ZHT_SYNONYM_OPTIMIZER);
48 }
49 v
50}
51
52pub trait Tokenizer: Send + Sync {
53 fn name(&self) -> &'static str;
54 fn split(&self, words: Vec<Word>, seg: &Segment) -> Vec<Word>;
55}
56
57pub trait Optimizer: Send + Sync {
58 fn name(&self) -> &'static str;
59 fn do_optimize(&self, words: Vec<Word>, seg: &Segment) -> Vec<Word>;
60}
61
62pub fn enabled(name: &str, disabled: &[String]) -> bool {
63 !disabled.iter().any(|d| d == name)
64}
65
66pub fn split_unknown(words: Vec<Word>, mut f: impl FnMut(&str) -> Option<Vec<Word>>) -> Vec<Word> {
68 let mut ret = Vec::new();
69 for word in words {
70 if word.is_recognized() {
71 ret.push(word);
72 continue;
73 }
74 match f(&word.w) {
75 Some(parts) => ret.extend(parts),
76 None => ret.push(word),
77 }
78 }
79 ret
80}
81
82pub fn split_unset(words: Vec<Word>, mut f: impl FnMut(&str) -> Option<Vec<Word>>) -> Vec<Word> {
84 let mut ret = Vec::new();
85 for word in words {
86 if word.has_pos() {
87 ret.push(word);
88 continue;
89 }
90 match f(&word.w) {
91 Some(parts) => ret.extend(parts),
92 None => ret.push(word),
93 }
94 }
95 ret
96}
97
98pub fn splice_token(words: &mut Vec<Word>, i: usize, len: usize, nw: Word) {
99 let end = (i + len).min(words.len());
100 words.splice(i..end, std::iter::once(nw));
101}
102
103pub fn splice_created(words: &mut Vec<Word>, i: usize, len: usize, mut nw: Word, seg: &Segment) {
105 if !seg.table.table.contains_key(&nw.w) {
106 nw.auto_create = true;
107 }
108 let end = (i + len).min(words.len());
109 if nw.m.is_none() && i < end {
110 nw.m = Some(words[i..end].to_vec());
111 }
112 splice_token(words, i, len, nw);
113}