Add two other "did you mean" messages

This commit is contained in:
Mubelotix
2025-08-13 13:16:25 +02:00
parent 666ae1a3e7
commit b80869f2be
4 changed files with 35 additions and 9 deletions

View File

@ -639,3 +639,29 @@ fn conditionally_lookup_for_error_message() {
assert_eq!(err.to_string(), format!("{} {}", prefix, suffix));
}
}
pub struct DidYouMean<'a>(Option<&'a str>);
impl<'a> DidYouMean<'a> {
pub fn new(key: &str, keys: &'a [String]) -> DidYouMean<'a> {
let typos = levenshtein_automata::LevenshteinAutomatonBuilder::new(2, true).build_dfa(key);
for key in keys.iter() {
match typos.eval(key) {
levenshtein_automata::Distance::Exact(_) => {
return DidYouMean(Some(key));
}
levenshtein_automata::Distance::AtLeast(_) => continue,
}
}
DidYouMean(None)
}
}
impl std::fmt::Display for DidYouMean<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(suggestion) = self.0 {
write!(f, " Did you mean `{suggestion}`?")?;
}
Ok(())
}
}

View File

@ -1,7 +1,7 @@
use filter_parser::{Token, VectorFilter};
use roaring::{MultiOps, RoaringBitmap};
use crate::error::Error;
use crate::error::{DidYouMean, Error};
use crate::vector::db::IndexEmbeddingConfig;
use crate::vector::{ArroyStats, ArroyWrapper};
use crate::Index;
@ -14,7 +14,8 @@ pub enum VectorFilterError<'a> {
} else {
let mut available = available.clone();
available.sort_unstable();
format!("Available embedders are: {}.", available.iter().map(|e| format!("`{e}`")).collect::<Vec<_>>().join(", "))
let did_you_mean = DidYouMean::new(embedder.value(), &available);
format!("Available embedders are: {}.{did_you_mean}", available.iter().map(|e| format!("`{e}`")).collect::<Vec<_>>().join(", "))
}
})]
EmbedderDoesNotExist { embedder: &'a Token<'a>, available: Vec<String> },
@ -25,7 +26,8 @@ pub enum VectorFilterError<'a> {
} else {
let mut available = available.clone();
available.sort_unstable();
format!("Available fragments on this embedder are: {}.", available.iter().map(|f| format!("`{f}`")).collect::<Vec<_>>().join(", "))
let did_you_mean = DidYouMean::new(fragment.value(), &available);
format!("Available fragments on this embedder are: {}.{did_you_mean}", available.iter().map(|f| format!("`{f}`")).collect::<Vec<_>>().join(", "))
}
})]
FragmentDoesNotExist {