indicium/simple/autocomplete/mod.rs
1mod context;
2mod global;
3mod keyword;
4
5use crate::simple::AutocompleteType;
6use std::hash::Hash;
7
8// -----------------------------------------------------------------------------
9
10impl<K: Hash + Ord> crate::simple::SearchIndex<K>{
11 /// Returns matching autocompleted keywords for the provided search string.
12 /// This function will use the `AutocompleteType` setting stored in the
13 /// `SearchIndex`. Partial keywords must be an exact match. Results are
14 /// returned in lexographic order.
15 ///
16 /// Autocompletion behaviour can be changed by setting the
17 /// [`AutocompleteType`] in the `SearchIndex`. See also:
18 /// [`SearchIndexBuilder`] and [`SearchIndex::new()`].
19 ///
20 /// [`AutocompleteType`]: enum.AutocompleteType.html
21 /// [`SearchIndexBuilder`]: struct.SearchIndexBuilder.html
22 /// [`SearchIndex::new()`]: struct.SearchIndex.html#method.new
23 ///
24 /// Basic usage:
25 ///
26 /// ```rust
27 /// # use indicium::simple::{AutocompleteType, Indexable, SearchIndex, SearchType};
28 /// # use pretty_assertions::assert_eq;
29 /// #
30 /// # struct MyStruct {
31 /// # title: String,
32 /// # year: u16,
33 /// # body: String,
34 /// # }
35 /// #
36 /// # impl Indexable for MyStruct {
37 /// # fn strings(&self) -> Vec<String> {
38 /// # vec![
39 /// # self.title.clone(),
40 /// # self.year.to_string(),
41 /// # self.body.clone(),
42 /// # ]
43 /// # }
44 /// # }
45 /// #
46 /// # let my_vec = vec![
47 /// # MyStruct {
48 /// # title: "Harold Godwinson".to_string(),
49 /// # year: 1066,
50 /// # body: "Last crowned Anglo-Saxon king of England.".to_string(),
51 /// # },
52 /// # MyStruct {
53 /// # title: "Edgar Ætheling".to_string(),
54 /// # year: 1066,
55 /// # body: "Last male member of the royal house of Cerdic of Wessex.".to_string(),
56 /// # },
57 /// # MyStruct {
58 /// # title: "William the Conqueror".to_string(),
59 /// # year: 1066,
60 /// # body: "First Norman monarch of England.".to_string(),
61 /// # },
62 /// # MyStruct {
63 /// # title: "William Rufus".to_string(),
64 /// # year: 1087,
65 /// # body: "Third son of William the Conqueror.".to_string(),
66 /// # },
67 /// # MyStruct {
68 /// # title: "Henry Beauclerc".to_string(),
69 /// # year: 1100,
70 /// # body: "Fourth son of William the Conqueror.".to_string(),
71 /// # },
72 /// # ];
73 /// #
74 /// # let mut search_index: SearchIndex<usize> = SearchIndex::default();
75 /// #
76 /// # my_vec
77 /// # .iter()
78 /// # .enumerate()
79 /// # .for_each(|(index, element)|
80 /// # search_index.insert(&index, element)
81 /// # );
82 /// #
83 /// let autocomplete_options = search_index.autocomplete("Edgar last c");
84 /// assert_eq!(autocomplete_options, vec!["edgar last cerdic".to_string()]);
85 /// ```
86 #[tracing::instrument(level = "trace", name = "autocomplete", skip(self))]
87 pub fn autocomplete(&self, string: &str) -> Vec<String> {
88 let autocomplete_options: Vec<String> = match &self.autocomplete_type {
89 AutocompleteType::Context => {
90 self.autocomplete_context(&self.maximum_autocomplete_options, string)
91 }
92 AutocompleteType::Global => {
93 self.autocomplete_global(&self.maximum_autocomplete_options, string)
94 }
95 AutocompleteType::Keyword => self
96 .autocomplete_keyword(&self.maximum_autocomplete_options, string)
97 .into_iter()
98 .map(std::string::ToString::to_string)
99 .collect(),
100 };
101
102 // For debug builds:
103 #[cfg(debug_assertions)]
104 tracing::debug!(
105 "{} autocomplete options for \"{}\".",
106 autocomplete_options.len(),
107 string,
108 );
109
110 autocomplete_options
111 }
112
113 /// This autocomplete method allows the caller to define an
114 /// `AutocompleteType` parameter, effectively overriding the index settings.
115 /// See [`AutocompleteType`] for more information on the different
116 /// autocomplete types.
117 ///
118 /// Returns matching autocompleted keywords for the provided search string.
119 /// Partial keywords must be an exact match. Results are returned in
120 /// lexographic order.
121 ///
122 /// [`AutocompleteType`]: enum.AutocompleteType.html
123 ///
124 /// Basic usage:
125 ///
126 /// ```rust
127 /// # use indicium::simple::{AutocompleteType, Indexable, SearchIndex, SearchType};
128 /// # use pretty_assertions::assert_eq;
129 /// #
130 /// # struct MyStruct {
131 /// # title: String,
132 /// # year: u16,
133 /// # body: String,
134 /// # }
135 /// #
136 /// # impl Indexable for MyStruct {
137 /// # fn strings(&self) -> Vec<String> {
138 /// # vec![
139 /// # self.title.clone(),
140 /// # self.year.to_string(),
141 /// # self.body.clone(),
142 /// # ]
143 /// # }
144 /// # }
145 /// #
146 /// # let my_vec = vec![
147 /// # MyStruct {
148 /// # title: "Harold Godwinson".to_string(),
149 /// # year: 1066,
150 /// # body: "Last crowned Anglo-Saxon king of England.".to_string(),
151 /// # },
152 /// # MyStruct {
153 /// # title: "Edgar Ætheling".to_string(),
154 /// # year: 1066,
155 /// # body: "Last male member of the royal house of Cerdic of Wessex.".to_string(),
156 /// # },
157 /// # MyStruct {
158 /// # title: "William the Conqueror".to_string(),
159 /// # year: 1066,
160 /// # body: "First Norman monarch of England.".to_string(),
161 /// # },
162 /// # MyStruct {
163 /// # title: "William Rufus".to_string(),
164 /// # year: 1087,
165 /// # body: "Third son of William the Conqueror.".to_string(),
166 /// # },
167 /// # MyStruct {
168 /// # title: "Henry Beauclerc".to_string(),
169 /// # year: 1100,
170 /// # body: "Fourth son of William the Conqueror.".to_string(),
171 /// # },
172 /// # ];
173 /// #
174 /// # let mut search_index: SearchIndex<usize> = SearchIndex::default();
175 /// #
176 /// # my_vec
177 /// # .iter()
178 /// # .enumerate()
179 /// # .for_each(|(index, element)|
180 /// # search_index.insert(&index, element)
181 /// # );
182 /// #
183 /// let autocomplete_options =
184 /// search_index.autocomplete_type(&AutocompleteType::Global, "1100 e");
185 ///
186 /// assert_eq!(
187 /// autocomplete_options,
188 /// vec![
189 /// "1100 edgar".to_string(),
190 /// "1100 edgar ætheling".to_string(),
191 /// "1100 england".to_string()
192 /// ]
193 /// );
194 /// ```
195 #[tracing::instrument(level = "trace", name = "autocomplete", skip(self))]
196 pub fn autocomplete_type(
197 &self,
198 autocomplete_type: &AutocompleteType,
199 string: &str,
200 ) -> Vec<String> {
201 let autocomplete_options: Vec<String> = match autocomplete_type {
202 AutocompleteType::Context => {
203 self.autocomplete_context(&self.maximum_autocomplete_options, string)
204 }
205 AutocompleteType::Global => {
206 self.autocomplete_global(&self.maximum_autocomplete_options, string)
207 }
208 AutocompleteType::Keyword => self
209 .autocomplete_keyword(&self.maximum_autocomplete_options, string)
210 .into_iter()
211 .map(std::string::ToString::to_string)
212 .collect(),
213 };
214
215 // For debug builds:
216 #[cfg(debug_assertions)]
217 tracing::debug!(
218 "{} autocomplete options for \"{}\".",
219 autocomplete_options.len(),
220 string,
221 );
222
223 autocomplete_options
224 }
225
226 /// This autocomplete method allows the caller to define a
227 /// `AutocompleteType` and the maximum number of autocomplete options to be
228 /// returned. These parameters override the index settings. See
229 /// [`AutocompleteType`] for more information on the different search types.
230 ///
231 /// Returns matching autocompleted keywords for the provided search string.
232 /// Partial keywords must be an exact match. Results are returned in
233 /// lexographic order.
234 ///
235 /// [`AutocompleteType`]: enum.AutocompleteType.html
236 ///
237 /// Basic usage:
238 ///
239 /// ```rust
240 /// # use indicium::simple::{AutocompleteType, Indexable, SearchIndex, SearchType};
241 /// # use pretty_assertions::assert_eq;
242 /// #
243 /// # struct MyStruct {
244 /// # title: String,
245 /// # year: u16,
246 /// # body: String,
247 /// # }
248 /// #
249 /// # impl Indexable for MyStruct {
250 /// # fn strings(&self) -> Vec<String> {
251 /// # vec![
252 /// # self.title.clone(),
253 /// # self.year.to_string(),
254 /// # self.body.clone(),
255 /// # ]
256 /// # }
257 /// # }
258 /// #
259 /// # let my_vec = vec![
260 /// # MyStruct {
261 /// # title: "Harold Godwinson".to_string(),
262 /// # year: 1066,
263 /// # body: "Last crowned Anglo-Saxon king of England.".to_string(),
264 /// # },
265 /// # MyStruct {
266 /// # title: "Edgar Ætheling".to_string(),
267 /// # year: 1066,
268 /// # body: "Last male member of the royal house of Cerdic of Wessex.".to_string(),
269 /// # },
270 /// # MyStruct {
271 /// # title: "William the Conqueror".to_string(),
272 /// # year: 1066,
273 /// # body: "First Norman monarch of England.".to_string(),
274 /// # },
275 /// # MyStruct {
276 /// # title: "William Rufus".to_string(),
277 /// # year: 1087,
278 /// # body: "Third son of William the Conqueror.".to_string(),
279 /// # },
280 /// # MyStruct {
281 /// # title: "Henry Beauclerc".to_string(),
282 /// # year: 1100,
283 /// # body: "Fourth son of William the Conqueror.".to_string(),
284 /// # },
285 /// # ];
286 /// #
287 /// # let mut search_index: SearchIndex<usize> = SearchIndex::default();
288 /// #
289 /// # my_vec
290 /// # .iter()
291 /// # .enumerate()
292 /// # .for_each(|(index, element)|
293 /// # search_index.insert(&index, element)
294 /// # );
295 /// #
296 /// let autocomplete_options =
297 /// search_index.autocomplete_with(
298 /// &AutocompleteType::Global,
299 /// &5,
300 /// "1100 e",
301 /// );
302 ///
303 /// assert_eq!(
304 /// autocomplete_options,
305 /// vec![
306 /// "1100 edgar".to_string(),
307 /// "1100 edgar ætheling".to_string(),
308 /// "1100 england".to_string()
309 /// ]
310 /// );
311 /// ```
312 #[tracing::instrument(level = "trace", name = "autocomplete", skip(self))]
313 pub fn autocomplete_with(
314 &self,
315 autocomplete_type: &AutocompleteType,
316 maximum_autocomplete_options: &usize,
317 string: &str,
318 ) -> Vec<String> {
319 let autocomplete_options: Vec<String> = match autocomplete_type {
320 AutocompleteType::Context => {
321 self.autocomplete_context(maximum_autocomplete_options, string)
322 }
323 AutocompleteType::Global => {
324 self.autocomplete_global(maximum_autocomplete_options, string)
325 }
326 AutocompleteType::Keyword => self
327 .autocomplete_keyword(maximum_autocomplete_options, string)
328 .into_iter()
329 .map(std::string::ToString::to_string)
330 .collect(),
331 };
332
333 // For debug builds:
334 #[cfg(debug_assertions)]
335 tracing::debug!(
336 "{} autocomplete options for \"{}\".",
337 autocomplete_options.len(),
338 string,
339 );
340
341 autocomplete_options
342 }
343}