opentitanlib/io/console/
logged.rs1use std::io::Write;
6use std::sync::Mutex;
7use std::task::{Context, Poll, ready};
8use std::time::SystemTime;
9
10use anyhow::Result;
11
12use super::ConsoleDevice;
13use crate::io::uart::{FlowControl, Parity, Uart};
14
15pub struct Logged<T> {
17 inner: T,
18 newline: Mutex<bool>,
20}
21
22impl<T> Logged<T> {
23 pub fn new(inner: T) -> Logged<T> {
24 Self {
25 inner,
26 newline: Mutex::new(true),
27 }
28 }
29}
30
31impl<T: ConsoleDevice> ConsoleDevice for Logged<T> {
32 fn poll_read(&self, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize>> {
33 let mut newline = self.newline.lock().unwrap();
35 let len = ready!(self.inner.poll_read(cx, buf))?;
36
37 let mut stdout = std::io::stdout().lock();
38 for ch in buf[..len].iter().copied() {
39 if *newline {
40 let t = humantime::format_rfc3339_millis(SystemTime::now());
41 stdout.write_fmt(format_args!("[{} console]", t))?;
42 }
43
44 *newline = ch == b'\n';
45
46 stdout.write_all(std::slice::from_ref(&ch))?;
47 }
48 stdout.flush()?;
49
50 Poll::Ready(Ok(len))
51 }
52
53 fn write(&self, buf: &[u8]) -> Result<()> {
54 self.inner.write(buf)
55 }
56}
57
58impl<T: Uart> Uart for Logged<T> {
59 fn get_baudrate(&self) -> Result<u32> {
60 self.inner.get_baudrate()
61 }
62
63 fn set_baudrate(&self, baudrate: u32) -> Result<()> {
64 self.inner.set_baudrate(baudrate)
65 }
66
67 fn get_flow_control(&self) -> Result<FlowControl> {
68 self.inner.get_flow_control()
69 }
70
71 fn set_flow_control(&self, flow_control: bool) -> Result<()> {
72 self.inner.set_flow_control(flow_control)
73 }
74
75 fn get_device_path(&self) -> Result<String> {
76 self.inner.get_device_path()
77 }
78
79 fn clear_rx_buffer(&self) -> Result<()> {
80 *self.newline.lock().unwrap() = true;
81 self.inner.clear_rx_buffer()
82 }
83
84 fn set_parity(&self, parity: Parity) -> Result<()> {
85 self.inner.set_parity(parity)
86 }
87
88 fn get_parity(&self) -> Result<Parity> {
89 self.inner.get_parity()
90 }
91
92 fn set_break(&self, enable: bool) -> Result<()> {
93 self.inner.set_break(enable)
94 }
95}