veloxity_core/log/
drain.rs1use crate::{
2 comm::messages::messages::StatustextMsg,
3 events::{COMM_RESPONSE_QUEUE_CAPACITY, CommResponse},
4 log::Logger,
5 ports::EventEmitPort,
6};
7
8const MAX_LOGS_PER_DRAIN: usize = 1;
9
10pub struct LogDrainCtx<'a> {
11 pub responses: EventEmitPort<'a, CommResponse, COMM_RESPONSE_QUEUE_CAPACITY>,
12 pub connected: bool,
13}
14
15pub fn drain_logs_to_comm_responses(mut ctx: LogDrainCtx<'_>) -> usize {
16 if !ctx.connected {
17 return 0;
18 }
19
20 let mut drained = 0;
21
22 while drained < MAX_LOGS_PER_DRAIN {
23 let Some(entry) = Logger::pop() else {
24 break;
25 };
26
27 let mut text = [0u8; 50];
28 let bytes = entry.message.as_str().as_bytes();
29 let len = bytes.len().min(text.len());
30 text[..len].copy_from_slice(&bytes[..len]);
31
32 if ctx
33 .responses
34 .emit(CommResponse::Statustext(StatustextMsg {
35 severity: entry.severity,
36 text,
37 }))
38 .is_err()
39 {
40 break;
41 }
42
43 drained += 1;
44 }
45
46 drained
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52 use crate::{
53 comm::messages::enums::Severity,
54 events::{COMM_RESPONSE_QUEUE_CAPACITY, EventQueue},
55 log_info, log_warn,
56 };
57
58 #[test]
59 fn drain_logs_queues_statustext_responses() {
60 while Logger::pop().is_some() {}
61
62 log_info!("hello");
63 log_warn!("world");
64
65 let mut responses = EventQueue::<CommResponse, COMM_RESPONSE_QUEUE_CAPACITY>::new();
66 let drained = drain_logs_to_comm_responses(LogDrainCtx {
67 responses: EventEmitPort::new(&mut responses),
68 connected: true,
69 });
70
71 assert_eq!(drained, 1);
72 match responses.pop().unwrap() {
73 CommResponse::Statustext(msg) => {
74 assert!(matches!(msg.severity, Severity::Info));
75 assert_eq!(&msg.text[..5], b"hello");
76 }
77 _ => panic!("expected statustext response"),
78 }
79
80 let drained = drain_logs_to_comm_responses(LogDrainCtx {
81 responses: EventEmitPort::new(&mut responses),
82 connected: true,
83 });
84
85 assert_eq!(drained, 1);
86 match responses.pop().unwrap() {
87 CommResponse::Statustext(msg) => {
88 assert!(matches!(msg.severity, Severity::Warning));
89 assert_eq!(&msg.text[..5], b"world");
90 }
91 _ => panic!("expected statustext response"),
92 }
93 }
94
95 #[test]
96 fn drain_logs_waits_for_companion_connection() {
97 while Logger::pop().is_some() {}
98
99 log_info!("buffered");
100
101 let mut responses = EventQueue::<CommResponse, COMM_RESPONSE_QUEUE_CAPACITY>::new();
102 let drained = drain_logs_to_comm_responses(LogDrainCtx {
103 responses: EventEmitPort::new(&mut responses),
104 connected: false,
105 });
106
107 assert_eq!(drained, 0);
108 assert!(responses.is_empty());
109
110 let drained = drain_logs_to_comm_responses(LogDrainCtx {
111 responses: EventEmitPort::new(&mut responses),
112 connected: true,
113 });
114
115 assert_eq!(drained, 1);
116 }
117}