#[cfg(any(
target_os = "linux",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "macos"
))]
mod unix;
#[cfg(target_os = "windows")]
mod windows;
use tokio::io::{AsyncRead, AsyncWrite};
#[cfg(any(
target_os = "linux",
target_os = "freebsd",
target_os = "openbsd",
target_os = "netbsd",
target_os = "macos"
))]
use unix::RawAsyncSerialPort;
#[cfg(target_os = "windows")]
use windows::RawAsyncSerialPort;
use crate::SyncSerialPort;
use std::{
io::{IoSlice, IoSliceMut, Result as IoResult},
path::{Path, PathBuf},
pin::Pin,
task::{Context, Poll},
};
use tokio::io::ReadBuf;
use valuable::Valuable;
#[derive(Debug, Valuable)]
pub struct AsyncSerialPort {
inner: RawAsyncSerialPort,
}
impl AsyncSerialPort {
pub fn available_ports() -> IoResult<Vec<PathBuf>> {
SyncSerialPort::available_ports()
}
pub fn new(path: impl AsRef<Path>) -> IoResult<Self> {
Ok(Self {
inner: RawAsyncSerialPort::new(SyncSerialPort::new(path)?)?,
})
}
pub fn try_clone(&self) -> IoResult<Self> {
let inner = self.inner.try_clone()?;
Ok(Self { inner })
}
pub async fn read(&self, buff: &mut [u8]) -> IoResult<usize> {
self.inner.read(buff).await
}
#[must_use]
pub const fn can_read_vectored() -> bool {
RawAsyncSerialPort::can_read_vectored()
}
pub async fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> IoResult<usize> {
self.inner.read_vectored(bufs).await
}
pub async fn write(&self, buff: &[u8]) -> IoResult<usize> {
self.inner.write(buff).await
}
pub async fn write_all(&self, buff: &[u8]) -> IoResult<()> {
let mut written = 0;
while written < buff.len() {
written += self.write(&buff[written..]).await?;
}
Ok(())
}
#[must_use]
pub const fn can_write_vectored() -> bool {
RawAsyncSerialPort::can_write_vectored()
}
pub async fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> IoResult<usize> {
self.inner.write_vectored(bufs).await
}
pub fn discard_buffers(&self) -> IoResult<()> {
self.inner.with_raw(SyncSerialPort::discard_buffers)
}
pub fn discard_input_buffer(&self) -> IoResult<()> {
self.inner.with_raw(SyncSerialPort::discard_input_buffer)
}
pub fn discard_output_buffer(&self) -> IoResult<()> {
self.inner.with_raw(SyncSerialPort::discard_output_buffer)
}
pub fn set_rts(&self, state: bool) -> IoResult<()> {
self.inner.with_raw(|raw| raw.set_rts(state))
}
pub fn read_cts(&self) -> IoResult<bool> {
self.inner.with_raw(SyncSerialPort::read_cts)
}
pub fn set_dtr(&self, state: bool) -> IoResult<()> {
self.inner.with_raw(|raw| raw.set_dtr(state))
}
pub fn read_dsr(&self) -> IoResult<bool> {
self.inner.with_raw(SyncSerialPort::read_dsr)
}
pub fn read_ri(&self) -> IoResult<bool> {
self.inner.with_raw(SyncSerialPort::read_ri)
}
pub fn read_cd(&self) -> IoResult<bool> {
self.inner.with_raw(SyncSerialPort::read_cd)
}
}
impl AsyncRead for AsyncSerialPort {
fn poll_read(
self: Pin<&mut Self>,
ctx: &mut Context<'_>,
buff: &mut ReadBuf<'_>,
) -> Poll<IoResult<()>> {
self.get_mut().inner.poll_read(ctx, buff)
}
}
impl AsyncWrite for AsyncSerialPort {
fn poll_write(
self: Pin<&mut Self>,
ctx: &mut Context<'_>,
buff: &[u8],
) -> Poll<IoResult<usize>> {
self.get_mut().inner.poll_write(ctx, buff)
}
fn poll_write_vectored(
self: Pin<&mut Self>,
ctx: &mut Context<'_>,
bufs: &[IoSlice<'_>],
) -> Poll<IoResult<usize>> {
self.get_mut().inner.poll_write_vectored(ctx, bufs)
}
fn poll_flush(self: Pin<&mut Self>, _ctx: &mut Context<'_>) -> Poll<IoResult<()>> {
Poll::Ready(Ok(()))
}
fn poll_shutdown(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<IoResult<()>> {
self.get_mut().inner.poll_shutdown(ctx)
}
}