diff --git a/milli/src/index.rs b/milli/src/index.rs index 81648fe1c..41bd85b93 100644 --- a/milli/src/index.rs +++ b/milli/src/index.rs @@ -1041,10 +1041,10 @@ impl Index { } /// List the words on which typo are not allowed - pub fn exact_words<'t>(&self, txn: &'t RoTxn) -> Result>> { + pub fn exact_words<'t>(&self, txn: &'t RoTxn) -> Result>>> { match self.main.get::<_, Str, ByteSlice>(txn, main_key::EXACT_WORDS)? { - Some(bytes) => Ok(fst::Set::new(bytes)?.map_data(Cow::Borrowed)?), - None => Ok(fst::Set::default().map_data(Cow::Owned)?), + Some(bytes) => Ok(Some(fst::Set::new(bytes)?.map_data(Cow::Borrowed)?)), + None => Ok(None), } } diff --git a/milli/src/search/query_tree.rs b/milli/src/search/query_tree.rs index 02fc0747a..2e53971d2 100644 --- a/milli/src/search/query_tree.rs +++ b/milli/src/search/query_tree.rs @@ -152,7 +152,7 @@ trait Context { } /// Returns the minimum word len for 1 and 2 typos. fn min_word_len_for_typo(&self) -> heed::Result<(u8, u8)>; - fn exact_words(&self) -> crate::Result>>; + fn exact_words(&self) -> crate::Result>>>; } /// The query tree builder is the interface to build a query tree. @@ -183,7 +183,7 @@ impl<'a> Context for QueryTreeBuilder<'a> { Ok((one, two)) } - fn exact_words(&self) -> crate::Result>> { + fn exact_words(&self) -> crate::Result>>> { self.index.exact_words(self.rtxn) } } @@ -277,13 +277,13 @@ pub struct TypoConfig<'a> { pub max_typos: u8, pub word_len_one_typo: u8, pub word_len_two_typo: u8, - pub exact_words: fst::Set>, + pub exact_words: Option>>, } /// Return the `QueryKind` of a word depending on `authorize_typos` /// and the provided word length. fn typos<'a>(word: String, authorize_typos: bool, config: TypoConfig<'a>) -> QueryKind { - if authorize_typos && !config.exact_words.contains(&word) { + if authorize_typos && !config.exact_words.map(|s| s.contains(&word)).unwrap_or(false) { let count = word.chars().count().min(u8::MAX as usize) as u8; if count < config.word_len_one_typo { QueryKind::exact(word) @@ -779,8 +779,8 @@ mod test { Ok((DEFAULT_MIN_WORD_LEN_ONE_TYPO, DEFAULT_MIN_WORD_LEN_TWO_TYPOS)) } - fn exact_words(&self) -> crate::Result>> { - Ok(fst::Set::new(Cow::Borrowed(self.exact_words.as_slice())).unwrap()) + fn exact_words(&self) -> crate::Result>>> { + Ok(Some(fst::Set::new(Cow::Borrowed(self.exact_words.as_slice())).unwrap())) } } @@ -1405,7 +1405,7 @@ mod test { #[test] fn test_min_word_len_typo() { - let exact_words = fst::Set::from_iter([b""]).unwrap().map_data(Cow::Owned).unwrap(); + let exact_words = Some(fst::Set::from_iter([b""]).unwrap().map_data(Cow::Owned).unwrap()); let config = TypoConfig { max_typos: 2, word_len_one_typo: 5, word_len_two_typo: 7, exact_words }; diff --git a/milli/src/update/settings.rs b/milli/src/update/settings.rs index bd1495b1c..829932d5c 100644 --- a/milli/src/update/settings.rs +++ b/milli/src/update/settings.rs @@ -1495,7 +1495,7 @@ mod tests { let words = btreeset! { S("Ab"), S("ac") }; builder.set_exact_words(words); assert!(builder.execute(|_| ()).is_ok()); - let exact_words = index.exact_words(&txn).unwrap(); + let exact_words = index.exact_words(&txn).unwrap().unwrap(); for word in exact_words.into_fst().stream().into_str_vec().unwrap() { assert!(word.0 == "ac" || word.0 == "ab"); }