feat(proxy-engine): add live TTS streaming interactions and incoming number range support
This commit is contained in:
@@ -273,8 +273,56 @@ pub fn normalize_routing_identity(value: &str) -> String {
|
||||
digits
|
||||
}
|
||||
|
||||
fn parse_numeric_range_value(value: &str) -> Option<(bool, &str)> {
|
||||
let trimmed = value.trim();
|
||||
if trimmed.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let (has_plus, digits) = if let Some(rest) = trimmed.strip_prefix('+') {
|
||||
(true, rest)
|
||||
} else {
|
||||
(false, trimmed)
|
||||
};
|
||||
|
||||
if digits.is_empty() || !digits.chars().all(|c| c.is_ascii_digit()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((has_plus, digits))
|
||||
}
|
||||
|
||||
fn matches_numeric_range_pattern(pattern: &str, value: &str) -> bool {
|
||||
let Some((start, end)) = pattern.split_once("..") else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let Some((start_plus, start_digits)) = parse_numeric_range_value(start) else {
|
||||
return false;
|
||||
};
|
||||
let Some((end_plus, end_digits)) = parse_numeric_range_value(end) else {
|
||||
return false;
|
||||
};
|
||||
let Some((value_plus, value_digits)) = parse_numeric_range_value(value) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if start_plus != end_plus || value_plus != start_plus {
|
||||
return false;
|
||||
}
|
||||
if start_digits.len() != end_digits.len() || value_digits.len() != start_digits.len() {
|
||||
return false;
|
||||
}
|
||||
if start_digits > end_digits {
|
||||
return false;
|
||||
}
|
||||
|
||||
value_digits >= start_digits && value_digits <= end_digits
|
||||
}
|
||||
|
||||
/// Test a value against a pattern string.
|
||||
/// - None/empty: matches everything (wildcard)
|
||||
/// - `start..end`: numeric range match
|
||||
/// - Trailing '*': prefix match
|
||||
/// - Starts with '/': regex match
|
||||
/// - Otherwise: exact match
|
||||
@@ -290,6 +338,10 @@ pub fn matches_pattern(pattern: Option<&str>, value: &str) -> bool {
|
||||
return value.starts_with(&pattern[..pattern.len() - 1]);
|
||||
}
|
||||
|
||||
if matches_numeric_range_pattern(pattern, value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Regex match: "/^\\+49/" or "/pattern/i"
|
||||
if pattern.starts_with('/') {
|
||||
if let Some(last_slash) = pattern[1..].rfind('/') {
|
||||
@@ -579,4 +631,24 @@ mod tests {
|
||||
assert_eq!(support.no_answer_timeout, Some(20));
|
||||
assert!(!support.ring_browsers);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn matches_pattern_supports_numeric_ranges() {
|
||||
assert!(matches_pattern(
|
||||
Some("042116767546..042116767548"),
|
||||
"042116767547"
|
||||
));
|
||||
assert!(!matches_pattern(
|
||||
Some("042116767546..042116767548"),
|
||||
"042116767549"
|
||||
));
|
||||
assert!(matches_pattern(
|
||||
Some("+4942116767546..+4942116767548"),
|
||||
"+4942116767547"
|
||||
));
|
||||
assert!(!matches_pattern(
|
||||
Some("+4942116767546..+4942116767548"),
|
||||
"042116767547"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user