use std::time::{Duration, Instant};
#[derive(Debug, Clone)]
pub struct Notification {
pub message: String,
pub severity: NotificationSeverity,
pub created_at: Instant,
pub ttl: Duration,
}
impl Notification {
pub fn new(message: String, severity: NotificationSeverity, ttl: Duration) -> Self {
Self {
message,
severity,
created_at: Instant::now(),
ttl,
}
}
pub fn is_expired(&self) -> bool {
self.created_at.elapsed() >= self.ttl
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NotificationSeverity {
Info,
Warning,
Error,
Success,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn notification_severity_equality() {
assert_eq!(NotificationSeverity::Info, NotificationSeverity::Info);
assert_ne!(NotificationSeverity::Info, NotificationSeverity::Error);
assert_eq!(NotificationSeverity::Success, NotificationSeverity::Success);
}
#[test]
fn notification_new_sets_fields() {
let msg = "Catalog reloaded".to_string();
let ttl = Duration::from_secs(5);
let n = Notification::new(msg.clone(), NotificationSeverity::Success, ttl);
assert_eq!(n.message, msg);
assert_eq!(n.severity, NotificationSeverity::Success);
assert_eq!(n.ttl, ttl);
assert!(!n.is_expired());
}
#[test]
fn notification_is_expired_with_zero_ttl() {
let n = Notification::new(
"gone".to_string(),
NotificationSeverity::Info,
Duration::ZERO,
);
assert!(n.is_expired());
}
#[test]
fn notification_clone_preserves_severity() {
let n = Notification::new(
"test".to_string(),
NotificationSeverity::Warning,
Duration::from_secs(3),
);
let cloned = n.clone();
assert_eq!(cloned.severity, NotificationSeverity::Warning);
assert_eq!(cloned.message, "test");
}
#[test]
fn notification_debug_does_not_panic() {
let n = Notification::new(
"debug test".to_string(),
NotificationSeverity::Error,
Duration::from_secs(10),
);
let _ = format!("{:?}", n);
}
}