use std::ops::Range;
use ratatui::style::{Color, Modifier, Style};
use regex::Regex;
use std::sync::LazyLock;
struct HighlightRule {
regex: Regex,
style: Style,
}
static RULES: LazyLock<Vec<HighlightRule>> = LazyLock::new(|| {
vec![
HighlightRule {
regex: Regex::new(r"(?i)\bAT\+?\w*").unwrap(),
style: Style::default().fg(Color::Rgb(189, 147, 249)), },
HighlightRule {
regex: Regex::new(r"\b(OK|READY|SUCCESS|DONE|PASS(ED)?)\b").unwrap(),
style: Style::default().fg(Color::Rgb(80, 250, 123)).add_modifier(Modifier::BOLD), },
HighlightRule {
regex: Regex::new(r"(?i)\b(ERROR|FAIL(ED|URE)?|FAULT|PANIC|ABORT)\b").unwrap(),
style: Style::default().fg(Color::Rgb(255, 85, 85)).add_modifier(Modifier::BOLD), },
HighlightRule {
regex: Regex::new(r"\b0x[0-9A-Fa-f]+\b").unwrap(),
style: Style::default().fg(Color::Rgb(255, 184, 108)), },
HighlightRule {
regex: Regex::new(r"\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b").unwrap(),
style: Style::default().fg(Color::Rgb(139, 233, 253)), },
HighlightRule {
regex: Regex::new(r#""[^"]*""#).unwrap(),
style: Style::default().fg(Color::Rgb(241, 250, 140)), },
HighlightRule {
regex: Regex::new(r"\b\d+(\.\d+)?\b").unwrap(),
style: Style::default().fg(Color::Rgb(80, 250, 123)), },
]
});
pub fn highlight_line(text: &str) -> Vec<(Range<usize>, Style)> {
let mut ranges: Vec<(Range<usize>, Style)> = Vec::new();
for rule in RULES.iter() {
for m in rule.regex.find_iter(text) {
let range = m.start()..m.end();
let overlaps = ranges.iter().any(|(r, _)| r.start < range.end && range.start < r.end);
if !overlaps {
ranges.push((range, rule.style));
}
}
}
ranges.sort_by_key(|(r, _)| r.start);
ranges
}