virtio_drivers/device/console/
embedded_io.rs

1//! Implementation of `embedded-io` traits for `VirtIOConsole`.
2
3use super::VirtIOConsole;
4use crate::{transport::Transport, Error, Hal};
5use core::cmp::min;
6use embedded_io::{BufRead, ErrorType, Read, ReadReady, Write};
7
8impl<H: Hal, T: Transport> ErrorType for VirtIOConsole<H, T> {
9    type Error = Error;
10}
11
12impl<H: Hal, T: Transport> Write for VirtIOConsole<H, T> {
13    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
14        if buf.is_empty() {
15            Ok(0)
16        } else {
17            self.send_bytes(buf)?;
18            Ok(buf.len())
19        }
20    }
21
22    fn flush(&mut self) -> Result<(), Self::Error> {
23        // We don't buffer writes, so nothing to do here.
24        Ok(())
25    }
26}
27
28impl<H: Hal, T: Transport> ReadReady for VirtIOConsole<H, T> {
29    fn read_ready(&mut self) -> Result<bool, Self::Error> {
30        self.finish_receive()?;
31        Ok(self.cursor != self.pending_len)
32    }
33}
34
35impl<H: Hal, T: Transport> Read for VirtIOConsole<H, T> {
36    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
37        if buf.is_empty() {
38            Ok(0)
39        } else {
40            self.wait_for_receive()?;
41            let read_length = min(buf.len(), self.pending_len - self.cursor);
42            buf[..read_length]
43                .copy_from_slice(&self.queue_buf_rx[self.cursor..self.cursor + read_length]);
44            Ok(read_length)
45        }
46    }
47}
48
49impl<H: Hal, T: Transport> BufRead for VirtIOConsole<H, T> {
50    fn fill_buf(&mut self) -> Result<&[u8], Self::Error> {
51        self.wait_for_receive()?;
52        Ok(&self.queue_buf_rx[self.cursor..self.pending_len])
53    }
54
55    fn consume(&mut self, amt: usize) {
56        assert!(self.cursor + amt <= self.pending_len);
57        self.cursor += amt;
58    }
59}