11//! Implementation of [`Serial`](https://docs.rs/embedded-hal/0.2.1/embedded_hal/serial/index.html)
22
3- use std:: io:: { Error as IoError , Read , Write } ;
3+ use std:: io:: { ErrorKind as IoErrorKind , Read , Write } ;
44
55use nb;
66
@@ -11,15 +11,22 @@ use serial_unix::TTYPort;
1111/// the `embedded-hal` traits.
1212pub struct Serial ( pub TTYPort ) ;
1313
14+ /// Helper to convert std::io::Error to the nb::Error
15+ fn translate_io_errors ( err : std:: io:: Error ) -> nb:: Error < IoErrorKind > {
16+ match err. kind ( ) {
17+ IoErrorKind :: WouldBlock | IoErrorKind :: TimedOut | IoErrorKind :: Interrupted => {
18+ nb:: Error :: WouldBlock
19+ }
20+ err => nb:: Error :: Other ( err) ,
21+ }
22+ }
23+
1424impl hal:: serial:: Read < u8 > for Serial {
15- type Error = IoError ;
25+ type Error = IoErrorKind ;
1626
1727 fn read ( & mut self ) -> nb:: Result < u8 , Self :: Error > {
1828 let mut buffer = [ 0 ; 1 ] ;
19- let bytes_read = self
20- . 0
21- . read ( & mut buffer)
22- . map_err ( |err| nb:: Error :: Other ( Self :: Error :: from ( err) ) ) ?;
29+ let bytes_read = self . 0 . read ( & mut buffer) . map_err ( translate_io_errors) ?;
2330 if bytes_read == 1 {
2431 Ok ( buffer[ 0 ] )
2532 } else {
@@ -29,39 +36,54 @@ impl hal::serial::Read<u8> for Serial {
2936}
3037
3138impl hal:: serial:: Write < u8 > for Serial {
32- type Error = IoError ;
39+ type Error = IoErrorKind ;
3340
3441 fn write ( & mut self , word : u8 ) -> nb:: Result < ( ) , Self :: Error > {
35- self . 0
36- . write ( & [ word] )
37- . map_err ( |err| nb:: Error :: Other ( Self :: Error :: from ( err) ) ) ?;
42+ self . 0 . write ( & [ word] ) . map_err ( translate_io_errors) ?;
3843 Ok ( ( ) )
3944 }
4045
4146 fn flush ( & mut self ) -> nb:: Result < ( ) , Self :: Error > {
42- self . 0
43- . flush ( )
44- . map_err ( |err| nb:: Error :: Other ( Self :: Error :: from ( err) ) )
47+ self . 0 . flush ( ) . map_err ( translate_io_errors)
4548 }
4649}
4750
4851#[ cfg( test) ]
4952mod test {
5053 use std:: path:: Path ;
5154
52- use hal:: serial:: Read ;
53- use std:: io:: Write ;
55+ use hal:: serial:: { Read , Write } ;
56+ use std:: io:: { Read as IoRead , Write as IoWrite } ;
5457
5558 use super :: * ;
5659
57- #[ test]
58- fn test_empty ( ) {
59- let ( mut master, _slave, name) =
60+ fn create_pty_and_serial ( ) -> ( std:: fs:: File , Serial ) {
61+ let ( master, _slave, name) =
6062 openpty:: openpty ( None , None , None ) . expect ( "Creating pty failed" ) ;
61- println ! ( "{:?}" , name) ;
62- let port = TTYPort :: open ( Path :: new ( & name) ) . unwrap ( ) ;
63- let mut serial = Serial ( port) ;
64- master. write ( & [ 1 ] ) . unwrap ( ) ;
65- serial. read ( ) . unwrap ( ) ;
63+ let port = TTYPort :: open ( Path :: new ( & name) ) . expect ( "Creating TTYPort failed" ) ;
64+ let serial = Serial ( port) ;
65+ ( master, serial)
66+ }
67+
68+ #[ test]
69+ fn test_empty_read ( ) {
70+ let ( mut _master, mut serial) = create_pty_and_serial ( ) ;
71+ assert_eq ! ( Err ( nb:: Error :: WouldBlock ) , serial. read( ) ) ;
72+ }
73+
74+ #[ test]
75+ fn test_read ( ) {
76+ let ( mut master, mut serial) = create_pty_and_serial ( ) ;
77+ master. write ( & [ 1 ] ) . expect ( "Write failed" ) ;
78+ assert_eq ! ( Ok ( 1 ) , serial. read( ) ) ;
79+ }
80+
81+ #[ test]
82+ fn test_write ( ) {
83+ let ( mut master, mut serial) = create_pty_and_serial ( ) ;
84+ serial. write ( 2 ) . expect ( "Write failed" ) ;
85+ let mut buf = [ 0 ; 2 ] ;
86+ assert_eq ! ( 1 , master. read( & mut buf) . unwrap( ) ) ;
87+ assert_eq ! ( buf, [ 2 , 0 ] ) ;
6688 }
6789}
0 commit comments