use ratatui::{
prelude::*,
text::{Line, Span},
};
use crate::model::{Notification, NotificationKind};
pub fn build_error_line(error: &str) -> Line<'static> {
Line::from(vec![
Span::styled(" Error: ", Style::default().fg(Color::White).bg(Color::Red)),
Span::styled(format!(" {} ", error), Style::default().fg(Color::Red)),
])
}
pub fn build_notification_title(
notification: &Notification,
max_width: Option<usize>,
) -> Line<'static> {
let (label, label_bg, text_fg) = match notification.kind {
NotificationKind::Success => ("Success:", Color::Green, Color::Green),
NotificationKind::Info => ("Info:", Color::Cyan, Color::Cyan),
NotificationKind::Warning => ("Warning:", Color::Yellow, Color::Yellow),
};
let message = ¬ification.message;
let separator_width = 3; let label_width = label.len() + 1; let message_display_width = message.chars().count() + 1; let full_width = separator_width + label_width + message_display_width;
let truncated_message = if let Some(max) = max_width {
if full_width > max {
let available = max.saturating_sub(separator_width + label_width + 2); if available == 0 {
return Line::from(vec![]);
}
let truncated: String = message.chars().take(available).collect();
format!("{}… ", truncated)
} else {
format!("{} ", message)
}
} else {
format!("{} ", message)
};
if truncated_message.trim().is_empty() || truncated_message == "… " {
return Line::from(vec![]);
}
Line::from(vec![
Span::raw(" | "),
Span::styled(
format!("{} ", label),
Style::default().fg(Color::Black).bg(label_bg),
),
Span::styled(truncated_message, Style::default().fg(text_fg)),
])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_build_error_line() {
let line = build_error_line("Connection failed");
assert_eq!(line.spans.len(), 2);
assert_eq!(line.spans[0].content, " Error: ");
assert_eq!(line.spans[1].content, " Connection failed ");
}
#[test]
fn test_build_error_line_with_special_chars() {
let line = build_error_line("Can't find file: /path/to/file");
assert!(!line.spans.is_empty());
}
}