pub fn keyword_trigger_match<'a>(keywords: &[String], raw_query: &'a str) -> Option<&'a str> {
let mut parts = raw_query.splitn(2, ' ');
let first = parts.next().unwrap_or("");
let rest = parts.next()?;
let first_lower = first.to_lowercase();
keywords
.iter()
.any(|kw| kw.to_lowercase() == first_lower)
.then_some(rest)
}
#[cfg(test)]
mod tests {
use super::keyword_trigger_match;
#[test]
fn requires_space_separated_trigger() {
let keywords = vec!["fy".to_string()];
assert_eq!(keyword_trigger_match(&keywords, "fy hello"), Some("hello"));
assert_eq!(keyword_trigger_match(&keywords, "fy"), None);
assert_eq!(keyword_trigger_match(&keywords, "fyhello"), None);
assert_eq!(keyword_trigger_match(&keywords, "xx hello"), None);
}
#[test]
fn case_insensitive() {
let keywords = vec!["Translate".to_string()];
assert_eq!(keyword_trigger_match(&keywords, "translate hi"), Some("hi"));
assert_eq!(keyword_trigger_match(&keywords, "TRANSLATE hi"), Some("hi"));
}
#[test]
fn empty_keywords_never_match() {
assert_eq!(keyword_trigger_match(&[], "fy hello"), None);
}
}