1use std::{
2 io,
3 ops::{Deref, DerefMut},
4 os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd},
5};
6
7pub use async_io::Async;
8use async_io::IoSafe;
9pub use serialport::{SerialPortBuilder, new};
10pub mod error {
11 pub use serialport::{Error, Result};
12}
13
14pub type AsyncSerialPort = Async<
15 IoSafeAdapter<
16 cfg_select! {
17 unix => serialport::TTYPort,
18 windows => serialport::COMPort,
19 },
20 >,
21>;
22pub trait AsyncSerialPortBuilder {
23 fn open_async(self) -> serialport::Result<AsyncSerialPort>;
24}
25
26impl AsyncSerialPortBuilder for serialport::SerialPortBuilder {
27 fn open_async(self) -> serialport::Result<AsyncSerialPort> {
28 self.open_native()
29 .map(IoSafeAdapter)
30 .and_then(|io| Async::new(io).map_err(From::from))
31 }
32}
33
34#[derive(Debug)]
36pub struct IoSafeAdapter<T>(T);
37
38impl<T> Deref for IoSafeAdapter<T> {
39 type Target = T;
40
41 fn deref(&self) -> &Self::Target {
42 &self.0
43 }
44}
45
46impl<T> DerefMut for IoSafeAdapter<T> {
47 fn deref_mut(&mut self) -> &mut Self::Target {
48 &mut self.0
49 }
50}
51
52impl<T: io::Read> io::Read for IoSafeAdapter<T> {
53 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
54 self.0.read(buf)
55 }
56}
57
58impl<T: io::Write> io::Write for IoSafeAdapter<T> {
59 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
60 self.0.write(buf)
61 }
62 fn flush(&mut self) -> io::Result<()> {
63 self.0.flush()
64 }
65}
66
67unsafe impl<T: io::Read + io::Write> IoSafe for IoSafeAdapter<T> {}
70
71impl<T: AsRawFd> AsRawFd for IoSafeAdapter<T> {
72 fn as_raw_fd(&self) -> RawFd {
73 self.0.as_raw_fd()
74 }
75}
76
77impl<T> AsFd for IoSafeAdapter<T>
78where
79 Self: AsRawFd,
80{
81 fn as_fd(&self) -> BorrowedFd<'_> {
82 unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
84 }
85}