Files
poimen-memory/crates/mem-core/src/optimizer/router.rs
T

172 lines
4.7 KiB
Rust
Raw Normal View History

//! Content Router — regex-based content type detection
use anyhow::Result;
use super::ContentType;
pub struct ContentRouter {
_confidence_threshold: f32,
}
impl ContentRouter {
/// Create router with regex-only detection
pub fn new() -> Result<Self> {
Ok(Self {
_confidence_threshold: 0.7,
})
}
/// Detect content type using regex heuristics
pub fn detect(&self, content: &str) -> Result<ContentType> {
Ok(self.regex_fallback(content))
}
/// Regex-based detection
fn regex_fallback(&self, content: &str) -> ContentType {
if is_json(content) {
return ContentType::Json;
}
if is_log(content) {
return ContentType::Log;
}
if is_diff(content) {
return ContentType::Diff;
}
if is_code(content) {
return ContentType::Code;
}
ContentType::Text
}
}
/// Check if content is valid JSON
fn is_json(content: &str) -> bool {
let trimmed = content.trim();
if !((trimmed.starts_with('{') || trimmed.starts_with('['))) {
return false;
}
serde_json::from_str::<serde_json::Value>(trimmed).is_ok()
}
/// Check if content looks like logs (timestamps, log levels, errors)
fn is_log(content: &str) -> bool {
let content_lower = content.to_lowercase();
let has_log_level = content_lower.contains("error:")
|| content_lower.contains("warn:")
|| content_lower.contains("info:")
|| content_lower.contains("debug:")
|| content_lower.contains("err!")
|| content.contains("ERROR")
|| content.contains("WARN")
|| content.contains("INFO")
|| content.contains("FAIL");
let has_timestamp = regex_contains(
content,
r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}",
);
let has_error_markers = content_lower.contains("exception")
|| content_lower.contains("stack trace")
|| content_lower.contains("at line")
|| content.contains("npm ERR!")
|| content.contains("error[")
|| content.contains("panic:");
has_log_level || (has_timestamp && has_error_markers)
}
/// Check if content looks like a unified diff
fn is_diff(content: &str) -> bool {
let has_diff_markers = content.contains("---") && content.contains("+++")
|| content.contains("@@");
has_diff_markers && (content.contains("+") || content.contains("-"))
}
/// Check if content looks like source code
fn is_code(content: &str) -> bool {
let lines: Vec<&str> = content.lines().collect();
let import_use_pattern =
regex_contains(content, r"^(import|use|require|include|from|package|class|def|fn|public|private|const|let|var|function)\b");
let has_brackets =
content.contains('{') && content.contains('}') || content.contains('[') && content.contains(']');
let has_indentation = lines.iter().any(|line| line.starts_with('\t') || line.starts_with(" "));
(import_use_pattern || has_brackets) && has_indentation
}
/// Helper to check if text contains a regex pattern
fn regex_contains(text: &str, pattern: &str) -> bool {
if let Ok(re) = regex::Regex::new(pattern) {
re.is_match(text)
} else {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_json_detection() {
let json = r#"{"key": "value", "number": 42}"#;
assert!(is_json(json));
}
#[test]
fn test_json_array_detection() {
let json = r#"[1, 2, 3, {"nested": true}]"#;
assert!(is_json(json));
}
#[test]
fn test_invalid_json_rejected() {
let not_json = r#"{"key": "value", invalid}"#;
assert!(!is_json(not_json));
}
#[test]
fn test_log_detection_with_error_level() {
let log = "2026-08-28T09:15:00Z ERROR: connection timeout";
assert!(is_log(log));
}
#[test]
fn test_log_detection_with_npm_err() {
let log = "npm ERR! 404 Not Found - [email protected]";
assert!(is_log(log));
}
#[test]
fn test_diff_detection() {
let diff = "--- a/file.txt\n+++ b/file.txt\n@@ -1,3 +1,3 @@\n-old\n+new";
assert!(is_diff(diff));
}
#[test]
fn test_code_detection() {
let code = r#"
fn main() {
println!("hello");
}
"#;
assert!(is_code(code));
}
#[test]
fn test_text_detection_fallback() {
let router = ContentRouter::new().unwrap();
assert_eq!(router.detect("This is just plain English text without any special structure.").unwrap(), ContentType::Text);
}
#[test]
fn test_router_json() {
let router = ContentRouter::new().unwrap();
assert_eq!(router.detect(r#"{"key": "value"}"#).unwrap(), ContentType::Json);
}
}