arcbox_virtio_console/
io.rs1use std::collections::VecDeque;
7use std::io::{Read, Write};
8
9pub trait ConsoleIo: Send + Sync {
11 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize>;
13
14 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize>;
16
17 fn flush(&mut self) -> std::io::Result<()>;
19}
20
21pub struct StdioConsole;
23
24impl ConsoleIo for StdioConsole {
25 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
26 std::io::stdin().read(buf)
27 }
28
29 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
30 std::io::stdout().write(buf)
31 }
32
33 fn flush(&mut self) -> std::io::Result<()> {
34 std::io::stdout().flush()
35 }
36}
37
38pub struct BufferConsole {
40 pub input: VecDeque<u8>,
42 pub output: Vec<u8>,
44}
45
46impl BufferConsole {
47 #[must_use]
49 pub const fn new() -> Self {
50 Self {
51 input: VecDeque::new(),
52 output: Vec::new(),
53 }
54 }
55
56 pub fn push_input(&mut self, data: &[u8]) {
58 self.input.extend(data);
59 }
60
61 pub fn take_output(&mut self) -> Vec<u8> {
63 std::mem::take(&mut self.output)
64 }
65}
66
67impl Default for BufferConsole {
68 fn default() -> Self {
69 Self::new()
70 }
71}
72
73impl ConsoleIo for BufferConsole {
74 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
75 let len = buf.len().min(self.input.len());
76 for (i, byte) in self.input.drain(..len).enumerate() {
77 buf[i] = byte;
78 }
79 Ok(len)
80 }
81
82 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
83 self.output.extend_from_slice(buf);
84 Ok(buf.len())
85 }
86
87 fn flush(&mut self) -> std::io::Result<()> {
88 Ok(())
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn test_buffer_console() {
98 let mut buffer = BufferConsole::new();
99
100 buffer.push_input(b"Hello");
101
102 let mut buf = [0u8; 10];
103 let n = buffer.read(&mut buf).unwrap();
104 assert_eq!(n, 5);
105 assert_eq!(&buf[..n], b"Hello");
106
107 buffer.write(b"World").unwrap();
108 let output = buffer.take_output();
109 assert_eq!(&output, b"World");
110 }
111
112 #[test]
113 fn test_buffer_console_empty_read() {
114 let mut buffer = BufferConsole::new();
115
116 let mut buf = [0u8; 10];
117 let n = buffer.read(&mut buf).unwrap();
118 assert_eq!(n, 0);
119 }
120
121 #[test]
122 fn test_buffer_console_partial_read() {
123 let mut buffer = BufferConsole::new();
124 buffer.push_input(b"Hello, World!");
125
126 let mut buf = [0u8; 5];
127 let n = buffer.read(&mut buf).unwrap();
128 assert_eq!(n, 5);
129 assert_eq!(&buf, b"Hello");
130
131 let mut buf2 = [0u8; 10];
132 let n2 = buffer.read(&mut buf2).unwrap();
133 assert_eq!(n2, 8);
134 assert_eq!(&buf2[..n2], b", World!");
135 }
136
137 #[test]
138 fn test_buffer_console_multiple_writes() {
139 let mut buffer = BufferConsole::new();
140
141 buffer.write(b"Hello").unwrap();
142 buffer.write(b" ").unwrap();
143 buffer.write(b"World").unwrap();
144
145 let output = buffer.take_output();
146 assert_eq!(&output, b"Hello World");
147 }
148
149 #[test]
150 fn test_buffer_console_flush() {
151 let mut buffer = BufferConsole::new();
152 assert!(buffer.flush().is_ok());
153 }
154
155 #[test]
156 fn test_buffer_console_default() {
157 let buffer = BufferConsole::default();
158 assert!(buffer.input.is_empty());
159 assert!(buffer.output.is_empty());
160 }
161}