1#![deny(missing_docs)]
8#![warn(rust_2018_idioms)]
9
10pub use mio_serial::{
12 available_ports, new, ClearBuffer, DataBits, Error, ErrorKind, FlowControl, Parity, SerialPort,
13 SerialPortBuilder, SerialPortInfo, SerialPortType, StopBits, UsbPortInfo,
14};
15
16use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
17
18#[cfg(unix)]
19use std::convert::TryFrom;
20use std::io::{Read, Result as IoResult, Write};
21use std::pin::Pin;
22use std::task::{Context, Poll};
23use std::time::Duration;
24
25#[cfg(feature = "codec")]
26pub mod frame;
27
28#[cfg(unix)]
29mod os_prelude {
30 pub use futures::ready;
31 pub use tokio::io::unix::AsyncFd;
32}
33
34#[cfg(windows)]
35mod os_prelude {
36 pub use std::mem;
37 pub use std::ops::{Deref, DerefMut};
38 pub use std::os::windows::prelude::*;
39 pub use tokio::net::windows::named_pipe;
40}
41
42use crate::os_prelude::*;
43
44pub type Result<T> = mio_serial::Result<T>;
46
47#[derive(Debug)]
57pub struct SerialStream {
58 #[cfg(unix)]
59 inner: AsyncFd<mio_serial::SerialStream>,
60 #[cfg(windows)]
66 inner: named_pipe::NamedPipeClient,
67 #[cfg(windows)]
69 com: mem::ManuallyDrop<mio_serial::SerialStream>,
70}
71
72impl SerialStream {
73 pub fn open(builder: &crate::SerialPortBuilder) -> crate::Result<Self> {
75 let port = mio_serial::SerialStream::open(builder)?;
76
77 #[cfg(unix)]
78 {
79 Ok(Self {
80 inner: AsyncFd::new(port)?,
81 })
82 }
83
84 #[cfg(windows)]
85 {
86 let handle = port.as_raw_handle();
87 let com = mem::ManuallyDrop::new(port);
89 Ok(Self {
90 inner: unsafe { named_pipe::NamedPipeClient::from_raw_handle(handle)? },
91 com,
92 })
93 }
94 }
95
96 #[cfg(unix)]
116 pub fn pair() -> crate::Result<(Self, Self)> {
117 let (master, slave) = mio_serial::SerialStream::pair()?;
118
119 let master = SerialStream {
120 inner: AsyncFd::new(master)?,
121 };
122 let slave = SerialStream {
123 inner: AsyncFd::new(slave)?,
124 };
125 Ok((master, slave))
126 }
127
128 #[cfg(unix)]
139 pub fn set_exclusive(&mut self, exclusive: bool) -> crate::Result<()> {
140 self.inner.get_mut().set_exclusive(exclusive)
141 }
142
143 #[cfg(unix)]
148 pub fn exclusive(&self) -> bool {
149 self.inner.get_ref().exclusive()
150 }
151
152 #[inline(always)]
154 fn borrow(&self) -> &mio_serial::SerialStream {
155 #[cfg(unix)]
156 {
157 self.inner.get_ref()
158 }
159 #[cfg(windows)]
160 {
161 self.com.deref()
162 }
163 }
164
165 #[inline(always)]
167 fn borrow_mut(&mut self) -> &mut mio_serial::SerialStream {
168 #[cfg(unix)]
169 {
170 self.inner.get_mut()
171 }
172 #[cfg(windows)]
173 {
174 self.com.deref_mut()
175 }
176 }
177 pub fn try_read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
186 #[cfg(unix)]
187 {
188 self.inner.get_mut().read(buf)
189 }
190 #[cfg(windows)]
191 {
192 self.inner.try_read(buf)
193 }
194 }
195
196 pub async fn readable(&self) -> IoResult<()> {
204 let _ = self.inner.readable().await?;
205 Ok(())
206 }
207
208 pub fn try_write(&mut self, buf: &[u8]) -> IoResult<usize> {
213 #[cfg(unix)]
214 {
215 self.inner.get_mut().write(buf)
216 }
217 #[cfg(windows)]
218 {
219 self.inner.try_write(buf)
220 }
221 }
222
223 pub async fn writable(&self) -> IoResult<()> {
231 let _ = self.inner.writable().await?;
232 Ok(())
233 }
234}
235
236#[cfg(unix)]
237impl AsyncRead for SerialStream {
238 fn poll_read(
256 self: Pin<&mut Self>,
257 cx: &mut Context<'_>,
258 buf: &mut ReadBuf<'_>,
259 ) -> Poll<IoResult<()>> {
260 loop {
261 let mut guard = ready!(self.inner.poll_read_ready(cx))?;
262
263 match guard.try_io(|inner| inner.get_ref().read(buf.initialize_unfilled())) {
264 Ok(Ok(bytes_read)) => {
265 buf.advance(bytes_read);
266 return Poll::Ready(Ok(()));
267 }
268 Ok(Err(err)) => {
269 return Poll::Ready(Err(err));
270 }
271 Err(_would_block) => continue,
272 }
273 }
274 }
275}
276
277#[cfg(unix)]
278impl AsyncWrite for SerialStream {
279 fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<IoResult<usize>> {
297 loop {
298 let mut guard = ready!(self.inner.poll_write_ready(cx))?;
299
300 match guard.try_io(|inner| inner.get_ref().write(buf)) {
301 Ok(result) => return Poll::Ready(result),
302 Err(_would_block) => continue,
303 }
304 }
305 }
306
307 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
308 loop {
309 let mut guard = ready!(self.inner.poll_write_ready(cx))?;
310 match guard.try_io(|inner| inner.get_ref().flush()) {
311 Ok(_) => return Poll::Ready(Ok(())),
312 Err(_would_block) => continue,
313 }
314 }
315 }
316
317 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
318 let _ = self.poll_flush(cx)?;
319 Ok(()).into()
320 }
321}
322
323#[cfg(windows)]
324impl AsyncRead for SerialStream {
325 fn poll_read(
326 self: Pin<&mut Self>,
327 cx: &mut Context<'_>,
328 buf: &mut ReadBuf<'_>,
329 ) -> Poll<IoResult<()>> {
330 let mut self_ = self;
331 Pin::new(&mut self_.inner).poll_read(cx, buf)
332 }
333}
334
335#[cfg(windows)]
336impl AsyncWrite for SerialStream {
337 fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<IoResult<usize>> {
338 let mut self_ = self;
339 Pin::new(&mut self_.inner).poll_write(cx, buf)
340 }
341
342 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
343 let mut self_ = self;
344 Pin::new(&mut self_.inner).poll_flush(cx)
345 }
346
347 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
348 let mut self_ = self;
349 Pin::new(&mut self_.inner).poll_shutdown(cx)
350 }
351}
352
353impl crate::SerialPort for SerialStream {
354 #[inline(always)]
355 fn name(&self) -> Option<String> {
356 self.borrow().name()
357 }
358
359 #[inline(always)]
360 fn baud_rate(&self) -> crate::Result<u32> {
361 self.borrow().baud_rate()
362 }
363
364 #[inline(always)]
365 fn data_bits(&self) -> crate::Result<crate::DataBits> {
366 self.borrow().data_bits()
367 }
368
369 #[inline(always)]
370 fn flow_control(&self) -> crate::Result<crate::FlowControl> {
371 self.borrow().flow_control()
372 }
373
374 #[inline(always)]
375 fn parity(&self) -> crate::Result<crate::Parity> {
376 self.borrow().parity()
377 }
378
379 #[inline(always)]
380 fn stop_bits(&self) -> crate::Result<crate::StopBits> {
381 self.borrow().stop_bits()
382 }
383
384 #[inline(always)]
385 fn timeout(&self) -> Duration {
386 Duration::from_secs(0)
387 }
388
389 #[inline(always)]
390 fn set_baud_rate(&mut self, baud_rate: u32) -> crate::Result<()> {
391 self.borrow_mut().set_baud_rate(baud_rate)
392 }
393
394 #[inline(always)]
395 fn set_data_bits(&mut self, data_bits: crate::DataBits) -> crate::Result<()> {
396 self.borrow_mut().set_data_bits(data_bits)
397 }
398
399 #[inline(always)]
400 fn set_flow_control(&mut self, flow_control: crate::FlowControl) -> crate::Result<()> {
401 self.borrow_mut().set_flow_control(flow_control)
402 }
403
404 #[inline(always)]
405 fn set_parity(&mut self, parity: crate::Parity) -> crate::Result<()> {
406 self.borrow_mut().set_parity(parity)
407 }
408
409 #[inline(always)]
410 fn set_stop_bits(&mut self, stop_bits: crate::StopBits) -> crate::Result<()> {
411 self.borrow_mut().set_stop_bits(stop_bits)
412 }
413
414 #[inline(always)]
415 fn set_timeout(&mut self, _: Duration) -> crate::Result<()> {
416 Ok(())
417 }
418
419 #[inline(always)]
420 fn write_request_to_send(&mut self, level: bool) -> crate::Result<()> {
421 self.borrow_mut().write_request_to_send(level)
422 }
423
424 #[inline(always)]
425 fn write_data_terminal_ready(&mut self, level: bool) -> crate::Result<()> {
426 self.borrow_mut().write_data_terminal_ready(level)
427 }
428
429 #[inline(always)]
430 fn read_clear_to_send(&mut self) -> crate::Result<bool> {
431 self.borrow_mut().read_clear_to_send()
432 }
433
434 #[inline(always)]
435 fn read_data_set_ready(&mut self) -> crate::Result<bool> {
436 self.borrow_mut().read_data_set_ready()
437 }
438
439 #[inline(always)]
440 fn read_ring_indicator(&mut self) -> crate::Result<bool> {
441 self.borrow_mut().read_ring_indicator()
442 }
443
444 #[inline(always)]
445 fn read_carrier_detect(&mut self) -> crate::Result<bool> {
446 self.borrow_mut().read_carrier_detect()
447 }
448
449 #[inline(always)]
450 fn bytes_to_read(&self) -> crate::Result<u32> {
451 self.borrow().bytes_to_read()
452 }
453
454 #[inline(always)]
455 fn bytes_to_write(&self) -> crate::Result<u32> {
456 self.borrow().bytes_to_write()
457 }
458
459 #[inline(always)]
460 fn clear(&self, buffer_to_clear: crate::ClearBuffer) -> crate::Result<()> {
461 self.borrow().clear(buffer_to_clear)
462 }
463
464 #[inline(always)]
469 fn try_clone(&self) -> crate::Result<Box<dyn crate::SerialPort>> {
470 Err(crate::Error::new(
471 crate::ErrorKind::Io(std::io::ErrorKind::Other),
472 "Cannot clone Tokio handles",
473 ))
474 }
475
476 #[inline(always)]
477 fn set_break(&self) -> crate::Result<()> {
478 self.borrow().set_break()
479 }
480
481 #[inline(always)]
482 fn clear_break(&self) -> crate::Result<()> {
483 self.borrow().clear_break()
484 }
485}
486
487impl Read for SerialStream {
488 fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
489 self.try_read(buf)
490 }
491}
492
493impl Write for SerialStream {
494 fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
495 self.try_write(buf)
496 }
497
498 fn flush(&mut self) -> IoResult<()> {
499 self.borrow_mut().flush()
500 }
501}
502
503#[cfg(unix)]
504impl TryFrom<serialport::TTYPort> for SerialStream {
505 type Error = Error;
506
507 fn try_from(value: serialport::TTYPort) -> std::result::Result<Self, Self::Error> {
508 let port = mio_serial::SerialStream::try_from(value)?;
509 Ok(Self {
510 inner: AsyncFd::new(port)?,
511 })
512 }
513}
514
515#[cfg(unix)]
516mod sys {
517 use super::SerialStream;
518 use std::os::unix::io::{AsRawFd, RawFd};
519 impl AsRawFd for SerialStream {
520 fn as_raw_fd(&self) -> RawFd {
521 self.inner.as_raw_fd()
522 }
523 }
524}
525
526#[cfg(windows)]
527mod io {
528 use super::SerialStream;
529 use std::os::windows::io::{AsRawHandle, RawHandle};
530 impl AsRawHandle for SerialStream {
531 fn as_raw_handle(&self) -> RawHandle {
532 self.inner.as_raw_handle()
533 }
534 }
535}
536
537pub trait SerialPortBuilderExt {
545 fn open_native_async(self) -> Result<SerialStream>;
547}
548
549impl SerialPortBuilderExt for SerialPortBuilder {
550 fn open_native_async(self) -> Result<SerialStream> {
552 SerialStream::open(&self)
553 }
554}