1use std::cell::{Ref, RefCell};
18use std::iter::FusedIterator;
19use std::ops::{Deref, DerefMut, Index};
20use std::rc::Rc;
21
22use crate::analysis::morpheme::Morpheme;
23use crate::analysis::node::{PathCost, ResultNode};
24use crate::analysis::stateful_tokenizer::StatefulTokenizer;
25use crate::analysis::{Mode, Node};
26use crate::dic::subset::InfoSubset;
27use crate::dic::{normalize_input_text, DictionaryAccess};
28use crate::error::{SudachiError, SudachiResult};
29use crate::input_text::InputBuffer;
30
31struct InputPart {
32 input: InputBuffer,
33 subset: InfoSubset,
34}
35
36impl Default for InputPart {
37 fn default() -> Self {
38 let mut input = InputBuffer::new();
39 input.start_build().unwrap();
40 Self {
41 input,
42 subset: Default::default(),
43 }
44 }
45}
46
47#[derive(Default)]
48struct Nodes {
49 data: Vec<ResultNode>,
50}
51
52impl Nodes {
53 fn mut_data(&mut self) -> &mut Vec<ResultNode> {
54 &mut self.data
55 }
56}
57
58pub struct MorphemeList<D> {
59 dict: D,
60 input: Rc<RefCell<InputPart>>,
61 nodes: Nodes,
62}
63
64impl<D: DictionaryAccess> MorphemeList<D> {
65 pub fn empty(dict: D) -> Self {
67 let input = Default::default();
68 Self {
69 dict,
70 input: Rc::new(RefCell::new(input)),
71 nodes: Default::default(),
72 }
73 }
74
75 pub fn from_components(
77 dict: D,
78 input: InputBuffer,
79 path: Vec<ResultNode>,
80 subset: InfoSubset,
81 ) -> Self {
82 let input = InputPart { input, subset };
83 Self {
84 dict,
85 input: Rc::new(RefCell::new(input)),
86 nodes: Nodes { data: path },
87 }
88 }
89
90 pub fn collect_results<U: DictionaryAccess>(
91 &mut self,
92 analyzer: &mut StatefulTokenizer<U>,
93 ) -> SudachiResult<()> {
94 match self.input.try_borrow_mut() {
95 Ok(mut i) => {
96 let mref = i.deref_mut();
97 analyzer.swap_result(&mut mref.input, self.nodes.mut_data(), &mut mref.subset);
98 Ok(())
99 }
100 Err(_) => Err(SudachiError::MorphemeListBorrowed),
101 }
102 }
103
104 pub fn split_into(&self, mode: Mode, index: usize, out: &mut Self) -> SudachiResult<bool> {
108 let node = self.node(index);
109 let num_splits = node.num_splits(mode);
110
111 if num_splits == 0 {
112 Ok(false)
113 } else {
114 out.assign_input(self);
115 let data = out.nodes.mut_data();
116 let input = self.input();
117 let subset = self.subset();
118 data.reserve(num_splits);
119 for n in node.split(mode, self.dict().lexicon(), subset, input.deref()) {
120 data.push(n);
121 }
122 Ok(true)
123 }
124 }
125
126 pub fn clear(&mut self) {
128 self.nodes.mut_data().clear();
129 }
130
131 pub fn len(&self) -> usize {
132 self.nodes.data.len()
133 }
134
135 pub fn is_empty(&self) -> bool {
136 self.nodes.data.is_empty()
137 }
138
139 pub fn get(&self, idx: usize) -> Morpheme<'_, D> {
140 Morpheme::for_list(self, idx)
141 }
142
143 pub fn surface(&self) -> Ref<'_, str> {
144 let inp = self.input();
145 Ref::map(inp, |i| i.original())
146 }
147
148 pub fn iter(&self) -> MorphemeIter<'_, D> {
149 MorphemeIter {
150 index: 0,
151 list: self,
152 }
153 }
154
155 pub fn get_internal_cost(&self) -> i32 {
157 let len = self.len();
158 if len == 0 {
159 return 0;
160 }
161
162 let first_node = self.node(0);
163 let last_node = self.node(len - 1);
164 last_node.total_cost() - first_node.total_cost()
165 }
166
167 pub(crate) fn node(&self, idx: usize) -> &ResultNode {
168 self.nodes.data.index(idx)
169 }
170
171 pub fn dict(&self) -> &D {
172 &self.dict
173 }
174
175 pub(crate) fn input(&self) -> Ref<'_, InputBuffer> {
176 Ref::map(self.input.deref().borrow(), |x| &x.input)
177 }
178
179 pub(crate) fn assign_input(&mut self, other: &Self) {
181 if self.input.as_ptr() != other.input.as_ptr() {
182 self.input = other.input.clone();
183 }
184 }
185
186 pub fn subset(&self) -> InfoSubset {
187 self.input.deref().borrow().subset
188 }
189
190 pub fn copy_slice(&self, start: usize, end: usize, out: &mut Self) {
191 let out_data = out.nodes.mut_data();
192 out_data.extend_from_slice(&self.nodes.data[start..end]);
193 }
194
195 pub fn lookup(&mut self, query: &str, subset: InfoSubset) -> SudachiResult<usize> {
200 let (normalized, end_chars) = {
201 let dict = &self.dict;
202 let input = &mut self.input.borrow_mut().input;
203 normalize_input_text(dict, query, input)?;
204 let normalized = input.current().to_owned();
205 input.reset().push_str(&normalized);
206 input.start_build()?;
207 input.build(dict.grammar())?;
208 let end_chars = input.ch_idx(normalized.len());
209 (normalized, end_chars)
210 };
211
212 let mut result = 0;
213 let lex = self.dict.lexicon();
214 for entry in lex.lookup(normalized.as_bytes(), 0) {
215 if entry.end != normalized.len() {
216 continue;
217 }
218 let info = lex.get_word_info_subset(entry.word_id, subset)?;
219 let node = Node::new(0, end_chars as _, 0, 0, 0, entry.word_id);
220 self.nodes
221 .data
222 .push(ResultNode::new(node, 0, 0, normalized.len() as _, info));
223 result += 1;
224 }
225 Ok(result)
226 }
227}
228
229impl<T: DictionaryAccess + Clone> MorphemeList<T> {
230 pub fn empty_clone(&self) -> Self {
231 Self {
232 dict: self.dict.clone(),
233 input: self.input.clone(),
234 nodes: Default::default(),
235 }
236 }
237
238 #[deprecated(note = "use split_into", since = "0.6.1")]
241 pub fn split(&self, mode: Mode, index: usize) -> SudachiResult<MorphemeList<T>> {
242 let mut list = self.empty_clone();
243 if !self.split_into(mode, index, &mut list)? {
244 list.nodes.mut_data().push(self.node(index).clone())
245 }
246 Ok(list)
247 }
248}
249
250pub struct MorphemeIter<'a, T> {
252 list: &'a MorphemeList<T>,
253 index: usize,
254}
255
256impl<'a, T: DictionaryAccess> Iterator for MorphemeIter<'a, T> {
257 type Item = Morpheme<'a, T>;
258
259 fn next(&mut self) -> Option<Self::Item> {
260 if self.index >= self.list.len() {
261 return None;
262 }
263
264 let morpheme = Morpheme::for_list(self.list, self.index);
265
266 self.index += 1;
267 Some(morpheme)
268 }
269
270 fn size_hint(&self) -> (usize, Option<usize>) {
271 let rem = self.list.len() - self.index;
272 (rem, Some(rem))
273 }
274}
275
276impl<'a, T: DictionaryAccess> FusedIterator for MorphemeIter<'a, T> {}
277
278impl<'a, T: DictionaryAccess> ExactSizeIterator for MorphemeIter<'a, T> {
279 fn len(&self) -> usize {
280 self.size_hint().0
281 }
282}