1 //! Implementation of `embedded-io` traits for `VirtIOConsole`. 2 3 use super::VirtIOConsole; 4 use crate::{transport::Transport, Error, Hal}; 5 use core::cmp::min; 6 use embedded_io::{BufRead, ErrorType, Read, ReadReady, Write}; 7 8 impl<H: Hal, T: Transport> ErrorType for VirtIOConsole<H, T> { 9 type Error = Error; 10 } 11 12 impl<H: Hal, T: Transport> Write for VirtIOConsole<H, T> { write(&mut self, buf: &[u8]) -> Result<usize, Self::Error>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 flush(&mut self) -> Result<(), Self::Error>22 fn flush(&mut self) -> Result<(), Self::Error> { 23 // We don't buffer writes, so nothing to do here. 24 Ok(()) 25 } 26 } 27 28 impl<H: Hal, T: Transport> ReadReady for VirtIOConsole<H, T> { read_ready(&mut self) -> Result<bool, Self::Error>29 fn read_ready(&mut self) -> Result<bool, Self::Error> { 30 self.finish_receive()?; 31 Ok(self.cursor != self.pending_len) 32 } 33 } 34 35 impl<H: Hal, T: Transport> Read for VirtIOConsole<H, T> { read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>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 49 impl<H: Hal, T: Transport> BufRead for VirtIOConsole<H, T> { fill_buf(&mut self) -> Result<&[u8], Self::Error>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 consume(&mut self, amt: usize)55 fn consume(&mut self, amt: usize) { 56 assert!(self.cursor + amt <= self.pending_len); 57 self.cursor += amt; 58 } 59 } 60