diff options
author | petr-tik <petr-tik@users.noreply.github.com> | 2019-07-31 00:16:02 +0100 |
---|---|---|
committer | Paul Masurel <paul.masurel@gmail.com> | 2019-07-31 08:16:02 +0900 |
commit | 0154dbe47778965af3772e08c046683456fe39a0 (patch) | |
tree | 5a2475b5a503b76c0ea5a55230860c1024f0a003 | |
parent | efd1af13255e614559fbf037d23dc0ae46f2dbd4 (diff) |
Replace unwrap with match and proper Error handling (#606)
* Replace unwrap with match and proper Error handling
* Replaced 'magic' values with a documented variable
Didn't like the unexplained 0..3 range, thought it was best as a variable
Calculating Levenshtein distance is expensive, so best explain why we should
keep it low
-rw-r--r-- | src/query/fuzzy_query.rs | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/query/fuzzy_query.rs b/src/query/fuzzy_query.rs index cffdb05..1b72a32 100644 --- a/src/query/fuzzy_query.rs +++ b/src/query/fuzzy_query.rs @@ -1,3 +1,4 @@ +use crate::error::TantivyError::InvalidArgument; use crate::query::{AutomatonWeight, Query, Weight}; use crate::schema::Term; use crate::Result; @@ -5,11 +6,16 @@ use crate::Searcher; use levenshtein_automata::{LevenshteinAutomatonBuilder, DFA}; use once_cell::sync::Lazy; use std::collections::HashMap; +use std::ops::Range; + +/// A range of Levenshtein distances that we will build DFAs for our terms +/// The computation is exponential, so best keep it to low single digits +const VALID_LEVENSHTEIN_DISTANCE_RANGE: Range<u8> = (0..3); static LEV_BUILDER: Lazy<HashMap<(u8, bool), LevenshteinAutomatonBuilder>> = Lazy::new(|| { let mut lev_builder_cache = HashMap::new(); // TODO make population lazy on a `(distance, val)` basis - for distance in 0..3 { + for distance in VALID_LEVENSHTEIN_DISTANCE_RANGE { for &transposition in &[false, true] { let lev_automaton_builder = LevenshteinAutomatonBuilder::new(distance, transposition); lev_builder_cache.insert((distance, transposition), lev_automaton_builder); @@ -100,10 +106,20 @@ impl FuzzyTermQuery { } fn specialized_weight(&self) -> Result<AutomatonWeight<DFA>> { - let automaton = LEV_BUILDER.get(&(self.distance, false)) - .unwrap() // TODO return an error - .build_dfa(self.term.text()); - Ok(AutomatonWeight::new(self.term.field(), automaton)) + // LEV_BUILDER is a HashMap, whose `get` method returns an Option + match LEV_BUILDER.get(&(self.distance, false)) { + // Unwrap the option and build the Ok(AutomatonWeight) + Some(automaton_builder) => { + let automaton = automaton_builder.build_dfa(self.term.text()); + Ok(AutomatonWeight::new(self.term.field(), automaton)) + } + None => { + return Err(InvalidArgument(format!( + "Levenshtein distance of {} is not allowed. Choose a value in the {:?} range", + self.distance, VALID_LEVENSHTEIN_DISTANCE_RANGE + ))) + } + } } } |