1
1
//! Implementation of [`Serial`](https://docs.rs/embedded-hal/0.2.1/embedded_hal/serial/index.html)
2
2
3
- use std:: io:: { Error as IoError , Read , Write } ;
3
+ use std:: io:: { ErrorKind as IoErrorKind , Read , Write } ;
4
4
5
5
use nb;
6
6
@@ -11,15 +11,22 @@ use serial_unix::TTYPort;
11
11
/// the `embedded-hal` traits.
12
12
pub struct Serial ( pub TTYPort ) ;
13
13
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
+
14
24
impl hal:: serial:: Read < u8 > for Serial {
15
- type Error = IoError ;
25
+ type Error = IoErrorKind ;
16
26
17
27
fn read ( & mut self ) -> nb:: Result < u8 , Self :: Error > {
18
28
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) ?;
23
30
if bytes_read == 1 {
24
31
Ok ( buffer[ 0 ] )
25
32
} else {
@@ -29,39 +36,54 @@ impl hal::serial::Read<u8> for Serial {
29
36
}
30
37
31
38
impl hal:: serial:: Write < u8 > for Serial {
32
- type Error = IoError ;
39
+ type Error = IoErrorKind ;
33
40
34
41
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) ?;
38
43
Ok ( ( ) )
39
44
}
40
45
41
46
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)
45
48
}
46
49
}
47
50
48
51
#[ cfg( test) ]
49
52
mod test {
50
53
use std:: path:: Path ;
51
54
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 } ;
54
57
55
58
use super :: * ;
56
59
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) =
60
62
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 ] ) ;
66
88
}
67
89
}
0 commit comments