metis_docs_tui/models/
message.rs1use std::time::{Duration, Instant};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum MessageType {
6 Error,
7 Success,
8 Warning,
9 Info,
10}
11
12impl MessageType {
13 pub fn duration(&self) -> Duration {
15 match self {
16 MessageType::Error => Duration::from_secs(10),
17 MessageType::Success => Duration::from_secs(5),
18 MessageType::Warning => Duration::from_secs(7),
19 MessageType::Info => Duration::from_secs(4),
20 }
21 }
22
23 pub fn prefix(&self) -> &'static str {
25 match self {
26 MessageType::Error => "ERROR",
27 MessageType::Success => "SUCCESS",
28 MessageType::Warning => "WARNING",
29 MessageType::Info => "INFO",
30 }
31 }
32}
33
34#[derive(Debug, Clone)]
36pub struct Message {
37 pub id: u64,
38 pub message_type: MessageType,
39 pub content: String,
40 pub created_at: Instant,
41 pub auto_clear: bool,
42}
43
44impl Message {
45 pub fn new(id: u64, message_type: MessageType, content: String) -> Self {
47 Self {
48 id,
49 message_type,
50 content,
51 created_at: Instant::now(),
52 auto_clear: true,
53 }
54 }
55
56 pub fn persistent(id: u64, message_type: MessageType, content: String) -> Self {
58 Self {
59 id,
60 message_type,
61 content,
62 created_at: Instant::now(),
63 auto_clear: false,
64 }
65 }
66
67 pub fn should_clear(&self) -> bool {
69 if !self.auto_clear {
70 return false;
71 }
72
73 let age = self.created_at.elapsed();
74 age >= self.message_type.duration()
75 }
76
77 pub fn display_text(&self) -> String {
79 format!("{}: {}", self.message_type.prefix(), self.content)
80 }
81}
82
83#[derive(Debug)]
85pub struct MessageState {
86 pub current_message: Option<Message>,
87 next_id: u64,
88}
89
90impl Default for MessageState {
91 fn default() -> Self {
92 Self::new()
93 }
94}
95
96impl MessageState {
97 pub fn new() -> Self {
99 Self {
100 current_message: None,
101 next_id: 1,
102 }
103 }
104
105 fn set_message(&mut self, message_type: MessageType, content: String) -> u64 {
107 let id = self.next_id;
108 self.next_id += 1;
109
110 let message = Message::new(id, message_type, content);
111 self.current_message = Some(message);
112
113 id
114 }
115
116 pub fn add_error(&mut self, content: String) -> u64 {
118 self.set_message(MessageType::Error, content)
119 }
120
121 pub fn add_success(&mut self, content: String) -> u64 {
123 self.set_message(MessageType::Success, content)
124 }
125
126 pub fn add_warning(&mut self, content: String) -> u64 {
128 self.set_message(MessageType::Warning, content)
129 }
130
131 pub fn add_info(&mut self, content: String) -> u64 {
133 self.set_message(MessageType::Info, content)
134 }
135
136 pub fn clear_message(&mut self) {
138 self.current_message = None;
139 }
140
141 pub fn clear_expired_messages(&mut self) {
143 if let Some(ref msg) = self.current_message {
144 if msg.should_clear() {
145 self.current_message = None;
146 }
147 }
148 }
149
150 pub fn get_current_message(&self) -> Option<&Message> {
152 self.current_message
153 .as_ref()
154 .filter(|msg| !msg.should_clear())
155 }
156
157 pub fn has_messages(&self) -> bool {
159 self.get_current_message().is_some()
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166
167 #[test]
168 fn test_message_creation() {
169 let msg = Message::new(1, MessageType::Error, "Test error".to_string());
170 assert_eq!(msg.id, 1);
171 assert_eq!(msg.message_type, MessageType::Error);
172 assert_eq!(msg.content, "Test error");
173 assert!(msg.auto_clear);
174 }
175
176 #[test]
177 fn test_persistent_message() {
178 let msg = Message::persistent(1, MessageType::Info, "Persistent info".to_string());
179 assert!(!msg.auto_clear);
180 assert!(!msg.should_clear());
181 }
182
183 #[test]
184 fn test_message_display_text() {
185 let msg = Message::new(1, MessageType::Success, "Operation completed".to_string());
186 assert_eq!(msg.display_text(), "SUCCESS: Operation completed");
187 }
188
189 #[test]
190 fn test_message_state_operations() {
191 let mut state = MessageState::new();
192
193 assert!(!state.has_messages());
195
196 state.add_error("Error 1".to_string());
198 assert!(state.has_messages());
199
200 state.add_success("Success 1".to_string());
202 assert!(state.has_messages());
203 if let Some(msg) = state.get_current_message() {
204 assert_eq!(msg.message_type, MessageType::Success);
205 assert_eq!(msg.content, "Success 1");
206 }
207
208 state.clear_message();
210 assert!(!state.has_messages());
211 }
212}