Skip to content

Commit

Permalink
Add tests and implement correct io::Error mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
rnestler committed Jun 6, 2019
1 parent fd946a2 commit 96e8151
Showing 1 changed file with 52 additions and 19 deletions.
71 changes: 52 additions & 19 deletions src/serial.rs
@@ -1,23 +1,33 @@
//! Implementation of [`Serial`](https://docs.rs/embedded-hal/0.2.1/embedded_hal/serial/index.html)

use std::io::{Read, Write, Error as IoError};
use std::io::{ErrorKind as IoErrorKind, Read, Write};

use nb;

use ::hal;
use ::serial_unix::TTYPort;
use hal;
use serial_unix::TTYPort;

/// Newtype around [`serial_unix::TTYPort`] that implements
/// the `embedded-hal` traits.
pub struct Serial(pub TTYPort);

/// Helper to convert std::io::Error to the nb::Error
fn translate_io_errors(err: std::io::Error) -> nb::Error<IoErrorKind> {
match err.kind() {
IoErrorKind::WouldBlock | IoErrorKind::TimedOut | IoErrorKind::Interrupted => nb::Error::WouldBlock,
err => nb::Error::Other(err),
}
}

impl hal::serial::Read<u8> for Serial {
type Error = IoError;
type Error = IoErrorKind;

fn read(&mut self) -> nb::Result<u8, Self::Error> {
let mut buffer = [0; 1];
let bytes_read = self.0.read(&mut buffer)
.map_err(|err| nb::Error::Other(Self::Error::from(err)))?;
let bytes_read = self
.0
.read(&mut buffer)
.map_err(translate_io_errors)?;
if bytes_read == 1 {
Ok(buffer[0])
} else {
Expand All @@ -27,35 +37,58 @@ impl hal::serial::Read<u8> for Serial {
}

impl hal::serial::Write<u8> for Serial {
type Error = IoError;
type Error = IoErrorKind;

fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> {
self.0.write(&[word])
.map_err(|err| nb::Error::Other(Self::Error::from(err)))?;
self.0
.write(&[word])
.map_err(translate_io_errors)?;
Ok(())
}

fn flush(&mut self) -> nb::Result<(), Self::Error> {
self.0.flush()
.map_err(|err| nb::Error::Other(Self::Error::from(err)))
self.0
.flush()
.map_err(translate_io_errors)
}
}

#[cfg(test)]
mod test {
use std::path::Path;

use ::hal::serial::Read;
use hal::serial::{Read, Write};
use std::io::{Read as IoRead, Write as IoWrite};

use super::*;

fn create_pty_and_serial() -> (std::fs::File, Serial) {
let (master, _slave, name) =
openpty::openpty(None, None, None).expect("Creating pty failed");
let port = TTYPort::open(Path::new(&name)).expect("Creating TTYPort failed");
let serial = Serial(port);
(master, serial)
}

#[test]
fn test_empty_read() {
let (mut _master, mut serial) = create_pty_and_serial();
assert_eq!(Err(nb::Error::WouldBlock), serial.read());
}

#[test]
fn test_read() {
let (mut master, mut serial) = create_pty_and_serial();
master.write(&[1]).expect("Write failed");
assert_eq!(Ok(1), serial.read());
}

#[test]
fn test_empty() {
let (mut master, _slave, name) = openpty::openpty(None, None, None).expect("Creating pty failed");
println!("{:?}", name);
let port = TTYPort::open(Path::new(&name)).unwrap();
let mut serial = Serial(port);
master.write(&[1]).unwrap();
serial.read().unwrap();
fn test_write() {
let (mut master, mut serial) = create_pty_and_serial();
serial.write(2).expect("Write failed");
let mut buf = [0; 2];
assert_eq!(1, master.read(&mut buf).unwrap());
assert_eq!(buf, [2, 0]);
}
}

0 comments on commit 96e8151

Please sign in to comment.