use regex::{Regex, RegexBuilder};
pub fn build_trigger_pattern(trigger: &str, assistant_name: &str) -> Regex {
let t = trigger.trim();
let t = if t.is_empty() {
format!("@{assistant_name}")
} else {
t.to_string()
};
RegexBuilder::new(&format!(r"^{}\b", regex::escape(&t)))
.case_insensitive(true)
.build()
.unwrap_or_else(|_| Regex::new("$^").expect("static regex"))
}
pub fn default_trigger(assistant_name: &str) -> String {
format!("@{assistant_name}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn matches_case_insensitively_at_start() {
let re = build_trigger_pattern("@Talon", "Talon");
assert!(re.is_match("@talon what's up"));
assert!(!re.is_match("hey @Talon"));
assert!(!re.is_match("@Talonx"));
}
#[test]
fn empty_trigger_uses_assistant_name() {
let re = build_trigger_pattern(" ", "Talon");
assert!(re.is_match("@Talon go"));
}
#[test]
fn regex_metacharacters_are_escaped() {
let re = build_trigger_pattern("a.b", "x");
assert!(re.is_match("a.b hi"));
assert!(!re.is_match("axb hi"));
}
}