1#![allow(dead_code)]
4
5#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy)]
9#[allow(dead_code)]
10pub enum MsgPriority {
11 Low,
12 Normal,
13 High,
14}
15
16#[derive(Debug, Clone)]
18#[allow(dead_code)]
19pub struct Message {
20 pub id: u64,
21 pub tag: String,
22 pub text: String,
23 pub priority: MsgPriority,
24}
25
26#[derive(Debug)]
28#[allow(dead_code)]
29pub struct MessageLog {
30 messages: Vec<Message>,
31 next_id: u64,
32 capacity: usize,
33}
34
35#[allow(dead_code)]
37pub fn new_message_log(capacity: usize) -> MessageLog {
38 MessageLog {
39 messages: Vec::new(),
40 next_id: 1,
41 capacity,
42 }
43}
44
45#[allow(dead_code)]
47pub fn ml_push(log: &mut MessageLog, tag: &str, text: &str, priority: MsgPriority) -> u64 {
48 if log.messages.len() >= log.capacity && !log.messages.is_empty() {
49 log.messages.remove(0);
50 }
51 let id = log.next_id;
52 log.next_id += 1;
53 log.messages.push(Message {
54 id,
55 tag: tag.to_string(),
56 text: text.to_string(),
57 priority,
58 });
59 id
60}
61
62#[allow(dead_code)]
64pub fn ml_get(log: &MessageLog, id: u64) -> Option<&Message> {
65 log.messages.iter().find(|m| m.id == id)
66}
67
68#[allow(dead_code)]
70pub fn ml_by_tag<'a>(log: &'a MessageLog, tag: &str) -> Vec<&'a Message> {
71 log.messages.iter().filter(|m| m.tag == tag).collect()
72}
73
74#[allow(dead_code)]
76pub fn ml_by_priority(log: &MessageLog, min: MsgPriority) -> Vec<&Message> {
77 log.messages.iter().filter(|m| m.priority >= min).collect()
78}
79
80#[allow(dead_code)]
82pub fn ml_len(log: &MessageLog) -> usize {
83 log.messages.len()
84}
85
86#[allow(dead_code)]
88pub fn ml_clear(log: &mut MessageLog) {
89 log.messages.clear();
90}
91
92#[allow(dead_code)]
94pub fn ml_last(log: &MessageLog) -> Option<&Message> {
95 log.messages.last()
96}
97
98#[allow(dead_code)]
100pub fn ml_to_json(log: &MessageLog) -> String {
101 let items: Vec<String> = log
102 .messages
103 .iter()
104 .map(|m| format!(r#"{{"id":{},"tag":"{}","text":"{}"}}"#, m.id, m.tag, m.text))
105 .collect();
106 format!("[{}]", items.join(","))
107}
108
109#[allow(dead_code)]
111pub fn ml_remove_tag(log: &mut MessageLog, tag: &str) {
112 log.messages.retain(|m| m.tag != tag);
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn test_push_and_len() {
121 let mut log = new_message_log(10);
122 ml_push(&mut log, "sys", "hello", MsgPriority::Normal);
123 assert_eq!(ml_len(&log), 1);
124 }
125
126 #[test]
127 fn test_capacity_eviction() {
128 let mut log = new_message_log(3);
129 let id1 = ml_push(&mut log, "a", "1", MsgPriority::Low);
130 ml_push(&mut log, "b", "2", MsgPriority::Low);
131 ml_push(&mut log, "c", "3", MsgPriority::Low);
132 ml_push(&mut log, "d", "4", MsgPriority::Low);
133 assert_eq!(ml_len(&log), 3);
134 assert!(ml_get(&log, id1).is_none());
135 }
136
137 #[test]
138 fn test_get_by_id() {
139 let mut log = new_message_log(10);
140 let id = ml_push(&mut log, "net", "connect", MsgPriority::High);
141 assert!(ml_get(&log, id).is_some_and(|m| m.tag == "net"));
142 }
143
144 #[test]
145 fn test_by_tag() {
146 let mut log = new_message_log(10);
147 ml_push(&mut log, "io", "read", MsgPriority::Normal);
148 ml_push(&mut log, "net", "send", MsgPriority::Normal);
149 assert_eq!(ml_by_tag(&log, "io").len(), 1);
150 }
151
152 #[test]
153 fn test_by_priority() {
154 let mut log = new_message_log(10);
155 ml_push(&mut log, "a", "x", MsgPriority::Low);
156 ml_push(&mut log, "b", "y", MsgPriority::High);
157 assert_eq!(ml_by_priority(&log, MsgPriority::High).len(), 1);
158 }
159
160 #[test]
161 fn test_clear() {
162 let mut log = new_message_log(10);
163 ml_push(&mut log, "t", "m", MsgPriority::Normal);
164 ml_clear(&mut log);
165 assert_eq!(ml_len(&log), 0);
166 }
167
168 #[test]
169 fn test_last() {
170 let mut log = new_message_log(10);
171 ml_push(&mut log, "a", "first", MsgPriority::Low);
172 ml_push(&mut log, "b", "last", MsgPriority::High);
173 assert!(ml_last(&log).is_some_and(|m| m.text == "last"));
174 }
175
176 #[test]
177 fn test_json() {
178 let mut log = new_message_log(10);
179 ml_push(&mut log, "sys", "ok", MsgPriority::Normal);
180 let j = ml_to_json(&log);
181 assert!(j.contains("sys"));
182 }
183
184 #[test]
185 fn test_remove_tag() {
186 let mut log = new_message_log(10);
187 ml_push(&mut log, "del", "x", MsgPriority::Normal);
188 ml_push(&mut log, "keep", "y", MsgPriority::Normal);
189 ml_remove_tag(&mut log, "del");
190 assert_eq!(ml_len(&log), 1);
191 }
192}