Skip to main content

async_serial/
lib.rs

1use std::{
2    ffi::OsStr,
3    fmt, io,
4    ops::{Deref, DerefMut},
5    os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd},
6};
7
8pub use async_io::Async;
9use async_io::IoSafe;
10pub use serial::{SerialPort, SerialPortSettings};
11pub mod error {
12    pub use serial::{Error, ErrorKind, Result};
13}
14
15pub fn open(port: &(impl AsRef<OsStr> + ?Sized)) -> serial::Result<Async<SystemPort>> {
16    let port = serial::open(port)?;
17    SystemPort::from_serial(port).map_err(From::from)
18}
19
20/// An [`IoSafe`] newtype for [`serial::SystemPort`], useful for [`Async`] wrapper.
21pub struct SystemPort(serial::SystemPort);
22
23impl SystemPort {
24    pub fn from_serial(port: serial::SystemPort) -> io::Result<Async<Self>> {
25        Async::new(Self(port))
26    }
27}
28
29impl Deref for SystemPort {
30    type Target = serial::SystemPort;
31
32    fn deref(&self) -> &Self::Target {
33        &self.0
34    }
35}
36
37impl DerefMut for SystemPort {
38    fn deref_mut(&mut self) -> &mut Self::Target {
39        &mut self.0
40    }
41}
42
43impl io::Read for SystemPort {
44    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
45        self.0.read(buf)
46    }
47}
48
49impl io::Write for SystemPort {
50    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
51        self.0.write(buf)
52    }
53    fn flush(&mut self) -> io::Result<()> {
54        self.0.flush()
55    }
56}
57
58/// # Safety:
59/// The implementation of [`io::Read`] and [`io::Write`] for [`serial::SystemPort`] is [`IoSafe`]
60unsafe impl IoSafe for SystemPort {}
61
62impl AsRawFd for SystemPort {
63    fn as_raw_fd(&self) -> RawFd {
64        self.0.as_raw_fd()
65    }
66}
67
68impl AsFd for SystemPort {
69    fn as_fd(&self) -> BorrowedFd<'_> {
70        // Safety: This fd lifespan is tied to the `serial::SystemPort`
71        unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
72    }
73}
74
75impl fmt::Debug for SystemPort {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        f.debug_tuple("SystemPort")
78            .field(&self.as_raw_fd())
79            .finish()
80    }
81}