use crate::Device;
use std::io::{Error, Read, Write};
use winter_maybe_async::maybe_async;
#[derive(Clone, Copy, Debug)]
pub struct ReadWriteDevice<I: Read, O: Write, E: Write> {
input: I,
output: O,
error: E,
}
impl<I: Read, O: Write, E: Write> ReadWriteDevice<I, O, E> {
pub const fn new(input: I, output: O, error: E) -> Self {
Self {
input,
output,
error,
}
}
pub const fn output(&self) -> &O {
&self.output
}
pub const fn error(&self) -> &E {
&self.error
}
}
impl<I: Read, O: Write, E: Write> Device for ReadWriteDevice<I, O, E> {
type Error = Error;
#[maybe_async]
fn read(&mut self) -> Result<Option<u8>, Self::Error> {
let mut buffer = [0u8; 1];
let count = self.input.read(&mut buffer)?;
Ok(if count == 0 { None } else { Some(buffer[0]) })
}
#[maybe_async]
fn write(&mut self, byte: u8) -> Result<(), Self::Error> {
self.output.write_all(&[byte])?;
Ok(())
}
#[maybe_async]
fn write_error(&mut self, byte: u8) -> Result<(), Self::Error> {
self.error.write_all(&[byte])?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec;
use stak_util::block_on;
use std::io::empty;
#[test]
fn read() {
let mut device = ReadWriteDevice::new([1, 2, 3].as_slice(), empty(), empty());
assert_eq!(block_on!(device.read()).unwrap(), Some(1));
assert_eq!(block_on!(device.read()).unwrap(), Some(2));
assert_eq!(block_on!(device.read()).unwrap(), Some(3));
assert_eq!(block_on!(device.read()).unwrap(), None);
}
#[test]
fn write() {
let mut device = ReadWriteDevice::new(empty(), vec![], empty());
block_on!(device.write(1)).unwrap();
block_on!(device.write(2)).unwrap();
block_on!(device.write(3)).unwrap();
assert_eq!(device.output(), &[1, 2, 3]);
}
#[test]
fn write_error() {
let mut device = ReadWriteDevice::new(empty(), empty(), vec![]);
block_on!(device.write_error(1)).unwrap();
block_on!(device.write_error(2)).unwrap();
block_on!(device.write_error(3)).unwrap();
assert_eq!(device.error(), &[1, 2, 3]);
}
}