• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! serialport-rs is a cross-platform serial port library.
2 //!
3 //! The goal of this library is to expose a cross-platform and platform-specific API for enumerating
4 //! and using blocking I/O with serial ports. This library exposes a similar API to that provided
5 //! by [Qt's `QSerialPort` library](https://doc.qt.io/qt-5/qserialport.html).
6 //!
7 //! # Feature Overview
8 //!
9 //! The library has been organized such that there is a high-level `SerialPort` trait that provides
10 //! a cross-platform API for accessing serial ports. This is the preferred method of interacting
11 //! with ports. The `SerialPort::new().open*()` and `available_ports()` functions in the root
12 //! provide cross-platform functionality.
13 //!
14 //! For platform-specific functionality, this crate is split into a `posix` and `windows` API with
15 //! corresponding `TTYPort` and `COMPort` structs (that both implement the `SerialPort` trait).
16 //! Using the platform-specific `SerialPort::new().open*()` functions will return the
17 //! platform-specific port object which allows access to platform-specific functionality.
18 
19 #![deny(
20     clippy::dbg_macro,
21     missing_docs,
22     missing_debug_implementations,
23     missing_copy_implementations
24 )]
25 // Document feature-gated elements on docs.rs. See
26 // https://doc.rust-lang.org/rustdoc/unstable-features.html?highlight=doc(cfg#doccfg-recording-what-platforms-or-features-are-required-for-code-to-be-present
27 // and
28 // https://doc.rust-lang.org/rustdoc/unstable-features.html#doc_auto_cfg-automatically-generate-doccfg
29 // for details.
30 #![cfg_attr(docsrs, feature(doc_auto_cfg))]
31 // Don't worry about needing to `unwrap()` or otherwise handle some results in
32 // doc tests.
33 #![doc(test(attr(allow(unused_must_use))))]
34 
35 use std::error::Error as StdError;
36 use std::fmt;
37 use std::io;
38 use std::str::FromStr;
39 use std::time::Duration;
40 
41 #[cfg(unix)]
42 mod posix;
43 #[cfg(unix)]
44 pub use posix::{BreakDuration, TTYPort};
45 
46 #[cfg(windows)]
47 mod windows;
48 #[cfg(windows)]
49 pub use windows::COMPort;
50 
51 #[cfg(test)]
52 pub(crate) mod tests;
53 
54 /// A type for results generated by interacting with serial ports
55 ///
56 /// The `Err` type is hard-wired to [`serialport::Error`](struct.Error.html).
57 pub type Result<T> = std::result::Result<T, Error>;
58 
59 /// Categories of errors that can occur when interacting with serial ports
60 ///
61 /// This list is intended to grow over time and it is not recommended to
62 /// exhaustively match against it.
63 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
64 pub enum ErrorKind {
65     /// The device is not available.
66     ///
67     /// This could indicate that the device is in use by another process or was
68     /// disconnected while performing I/O.
69     NoDevice,
70 
71     /// A parameter was incorrect.
72     InvalidInput,
73 
74     /// An unknown error occurred.
75     Unknown,
76 
77     /// An I/O error occurred.
78     ///
79     /// The type of I/O error is determined by the inner `io::ErrorKind`.
80     Io(io::ErrorKind),
81 }
82 
83 /// An error type for serial port operations
84 #[derive(Debug, Clone)]
85 pub struct Error {
86     /// The kind of error this is
87     pub kind: ErrorKind,
88     /// A description of the error suitable for end-users
89     pub description: String,
90 }
91 
92 impl Error {
93     /// Instantiates a new error
new<T: Into<String>>(kind: ErrorKind, description: T) -> Self94     pub fn new<T: Into<String>>(kind: ErrorKind, description: T) -> Self {
95         Error {
96             kind,
97             description: description.into(),
98         }
99     }
100 
101     /// Returns the corresponding `ErrorKind` for this error.
kind(&self) -> ErrorKind102     pub fn kind(&self) -> ErrorKind {
103         self.kind
104     }
105 }
106 
107 impl fmt::Display for Error {
fmt(&self, fmt: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error>108     fn fmt(&self, fmt: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
109         fmt.write_str(&self.description)
110     }
111 }
112 
113 impl StdError for Error {
description(&self) -> &str114     fn description(&self) -> &str {
115         &self.description
116     }
117 }
118 
119 impl From<io::Error> for Error {
from(io_error: io::Error) -> Error120     fn from(io_error: io::Error) -> Error {
121         Error::new(ErrorKind::Io(io_error.kind()), format!("{}", io_error))
122     }
123 }
124 
125 impl From<Error> for io::Error {
from(error: Error) -> io::Error126     fn from(error: Error) -> io::Error {
127         let kind = match error.kind {
128             ErrorKind::NoDevice => io::ErrorKind::NotFound,
129             ErrorKind::InvalidInput => io::ErrorKind::InvalidInput,
130             ErrorKind::Unknown => io::ErrorKind::Other,
131             ErrorKind::Io(kind) => kind,
132         };
133 
134         io::Error::new(kind, error.description)
135     }
136 }
137 
138 /// Number of bits per character
139 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
140 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
141 pub enum DataBits {
142     /// 5 bits per character
143     Five,
144 
145     /// 6 bits per character
146     Six,
147 
148     /// 7 bits per character
149     Seven,
150 
151     /// 8 bits per character
152     Eight,
153 }
154 
155 impl fmt::Display for DataBits {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result156     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157         match *self {
158             DataBits::Five => write!(f, "Five"),
159             DataBits::Six => write!(f, "Six"),
160             DataBits::Seven => write!(f, "Seven"),
161             DataBits::Eight => write!(f, "Eight"),
162         }
163     }
164 }
165 
166 impl From<DataBits> for u8 {
from(value: DataBits) -> Self167     fn from(value: DataBits) -> Self {
168         match value {
169             DataBits::Five => 5,
170             DataBits::Six => 6,
171             DataBits::Seven => 7,
172             DataBits::Eight => 8,
173         }
174     }
175 }
176 
177 impl TryFrom<u8> for DataBits {
178     type Error = ();
179 
try_from(value: u8) -> core::result::Result<Self, Self::Error>180     fn try_from(value: u8) -> core::result::Result<Self, Self::Error> {
181         match value {
182             5 => Ok(Self::Five),
183             6 => Ok(Self::Six),
184             7 => Ok(Self::Seven),
185             8 => Ok(Self::Eight),
186             _ => Err(()),
187         }
188     }
189 }
190 
191 /// Parity checking modes
192 ///
193 /// When parity checking is enabled (`Odd` or `Even`) an extra bit is transmitted with
194 /// each character. The value of the parity bit is arranged so that the number of 1 bits in the
195 /// character (including the parity bit) is an even number (`Even`) or an odd number
196 /// (`Odd`).
197 ///
198 /// Parity checking is disabled by setting `None`, in which case parity bits are not
199 /// transmitted.
200 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
201 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
202 pub enum Parity {
203     /// No parity bit.
204     None,
205 
206     /// Parity bit sets odd number of 1 bits.
207     Odd,
208 
209     /// Parity bit sets even number of 1 bits.
210     Even,
211 }
212 
213 impl fmt::Display for Parity {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result214     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
215         match *self {
216             Parity::None => write!(f, "None"),
217             Parity::Odd => write!(f, "Odd"),
218             Parity::Even => write!(f, "Even"),
219         }
220     }
221 }
222 
223 /// Number of stop bits
224 ///
225 /// Stop bits are transmitted after every character.
226 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
227 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
228 pub enum StopBits {
229     /// One stop bit.
230     One,
231 
232     /// Two stop bits.
233     Two,
234 }
235 
236 impl fmt::Display for StopBits {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result237     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238         match *self {
239             StopBits::One => write!(f, "One"),
240             StopBits::Two => write!(f, "Two"),
241         }
242     }
243 }
244 
245 impl From<StopBits> for u8 {
from(value: StopBits) -> Self246     fn from(value: StopBits) -> Self {
247         match value {
248             StopBits::One => 1,
249             StopBits::Two => 2,
250         }
251     }
252 }
253 
254 impl TryFrom<u8> for StopBits {
255     type Error = ();
256 
try_from(value: u8) -> core::result::Result<Self, Self::Error>257     fn try_from(value: u8) -> core::result::Result<Self, Self::Error> {
258         match value {
259             1 => Ok(Self::One),
260             2 => Ok(Self::Two),
261             _ => Err(()),
262         }
263     }
264 }
265 
266 /// Flow control modes
267 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
268 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
269 pub enum FlowControl {
270     /// No flow control.
271     None,
272 
273     /// Flow control using XON/XOFF bytes.
274     Software,
275 
276     /// Flow control using RTS/CTS signals.
277     Hardware,
278 }
279 
280 impl fmt::Display for FlowControl {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result281     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282         match *self {
283             FlowControl::None => write!(f, "None"),
284             FlowControl::Software => write!(f, "Software"),
285             FlowControl::Hardware => write!(f, "Hardware"),
286         }
287     }
288 }
289 
290 impl FromStr for FlowControl {
291     type Err = ();
292 
from_str(s: &str) -> core::result::Result<Self, Self::Err>293     fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
294         match s {
295             "None" | "none" | "n" => Ok(FlowControl::None),
296             "Software" | "software" | "SW" | "sw" | "s" => Ok(FlowControl::Software),
297             "Hardware" | "hardware" | "HW" | "hw" | "h" => Ok(FlowControl::Hardware),
298             _ => Err(()),
299         }
300     }
301 }
302 
303 /// Specifies which buffer or buffers to purge when calling [`clear`]
304 ///
305 /// [`clear`]: trait.SerialPort.html#tymethod.clear
306 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
307 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
308 pub enum ClearBuffer {
309     /// Specify to clear data received but not read
310     Input,
311     /// Specify to clear data written but not yet transmitted
312     Output,
313     /// Specify to clear both data received and data not yet transmitted
314     All,
315 }
316 
317 /// A struct containing all serial port settings
318 #[derive(Debug, Clone, PartialEq, Eq)]
319 pub struct SerialPortBuilder {
320     /// The port name, usually the device path
321     path: String,
322     /// The baud rate in symbols-per-second
323     baud_rate: u32,
324     /// Number of bits used to represent a character sent on the line
325     data_bits: DataBits,
326     /// The type of signalling to use for controlling data transfer
327     flow_control: FlowControl,
328     /// The type of parity to use for error checking
329     parity: Parity,
330     /// Number of bits to use to signal the end of a character
331     stop_bits: StopBits,
332     /// Amount of time to wait to receive data before timing out
333     timeout: Duration,
334     /// The state to set DTR to when opening the device
335     dtr_on_open: Option<bool>,
336 }
337 
338 impl SerialPortBuilder {
339     /// Set the path to the serial port
340     // TODO: Switch to `clone_into` when bumping our MSRV past 1.63 and remove this exemption.
341     #[allow(clippy::assigning_clones)]
342     #[must_use]
path<'a>(mut self, path: impl Into<std::borrow::Cow<'a, str>>) -> Self343     pub fn path<'a>(mut self, path: impl Into<std::borrow::Cow<'a, str>>) -> Self {
344         self.path = path.into().as_ref().to_owned();
345         self
346     }
347 
348     /// Set the baud rate in symbols-per-second
349     #[must_use]
baud_rate(mut self, baud_rate: u32) -> Self350     pub fn baud_rate(mut self, baud_rate: u32) -> Self {
351         self.baud_rate = baud_rate;
352         self
353     }
354 
355     /// Set the number of bits used to represent a character sent on the line
356     #[must_use]
data_bits(mut self, data_bits: DataBits) -> Self357     pub fn data_bits(mut self, data_bits: DataBits) -> Self {
358         self.data_bits = data_bits;
359         self
360     }
361 
362     /// Set the type of signalling to use for controlling data transfer
363     #[must_use]
flow_control(mut self, flow_control: FlowControl) -> Self364     pub fn flow_control(mut self, flow_control: FlowControl) -> Self {
365         self.flow_control = flow_control;
366         self
367     }
368 
369     /// Set the type of parity to use for error checking
370     #[must_use]
parity(mut self, parity: Parity) -> Self371     pub fn parity(mut self, parity: Parity) -> Self {
372         self.parity = parity;
373         self
374     }
375 
376     /// Set the number of bits to use to signal the end of a character
377     #[must_use]
stop_bits(mut self, stop_bits: StopBits) -> Self378     pub fn stop_bits(mut self, stop_bits: StopBits) -> Self {
379         self.stop_bits = stop_bits;
380         self
381     }
382 
383     /// Set the amount of time to wait to receive data before timing out
384     ///
385     /// <div class="warning">
386     ///
387     /// The accuracy is limited by the underlying platform's capabilities. Longer timeouts will be
388     /// clamped to the maximum supported value which is expected to be in the magnitude of a few
389     /// days.
390     ///
391     /// </div>
392     #[must_use]
timeout(mut self, timeout: Duration) -> Self393     pub fn timeout(mut self, timeout: Duration) -> Self {
394         self.timeout = timeout;
395         self
396     }
397 
398     /// Set data terminal ready (DTR) to the given state when opening the device
399     #[must_use]
dtr_on_open(mut self, state: bool) -> Self400     pub fn dtr_on_open(mut self, state: bool) -> Self {
401         self.dtr_on_open = Some(state);
402         self
403     }
404 
405     /// Preserve the state of data terminal ready (DTR) when opening the device. Your outcome may
406     /// vary depending on the operation system. For example, Linux sets DTR by default and Windows
407     /// doesn't.
408     #[must_use]
preserve_dtr_on_open(mut self) -> Self409     pub fn preserve_dtr_on_open(mut self) -> Self {
410         self.dtr_on_open = None;
411         self
412     }
413 
414     /// Open a cross-platform interface to the port with the specified settings
open(self) -> Result<Box<dyn SerialPort>>415     pub fn open(self) -> Result<Box<dyn SerialPort>> {
416         #[cfg(unix)]
417         return posix::TTYPort::open(&self).map(|p| Box::new(p) as Box<dyn SerialPort>);
418 
419         #[cfg(windows)]
420         return windows::COMPort::open(&self).map(|p| Box::new(p) as Box<dyn SerialPort>);
421 
422         #[cfg(not(any(unix, windows)))]
423         Err(Error::new(
424             ErrorKind::Unknown,
425             "open() not implemented for platform",
426         ))
427     }
428 
429     /// Open a platform-specific interface to the port with the specified settings
430     #[cfg(unix)]
open_native(self) -> Result<TTYPort>431     pub fn open_native(self) -> Result<TTYPort> {
432         posix::TTYPort::open(&self)
433     }
434 
435     /// Open a platform-specific interface to the port with the specified settings
436     #[cfg(windows)]
open_native(self) -> Result<COMPort>437     pub fn open_native(self) -> Result<COMPort> {
438         windows::COMPort::open(&self)
439     }
440 }
441 
442 /// A trait for serial port devices
443 ///
444 /// This trait is all that's necessary to implement a new serial port driver
445 /// for a new platform.
446 pub trait SerialPort: Send + io::Read + io::Write {
447     // Port settings getters
448 
449     /// Returns the name of this port if it exists.
450     ///
451     /// This name may not be the canonical device name and instead be shorthand.
452     /// Additionally it may not exist for virtual ports.
name(&self) -> Option<String>453     fn name(&self) -> Option<String>;
454 
455     /// Returns the current baud rate.
456     ///
457     /// This may return a value different from the last specified baud rate depending on the
458     /// platform as some will return the actual device baud rate rather than the last specified
459     /// baud rate.
baud_rate(&self) -> Result<u32>460     fn baud_rate(&self) -> Result<u32>;
461 
462     /// Returns the character size.
463     ///
464     /// This function returns `None` if the character size could not be determined. This may occur
465     /// if the hardware is in an uninitialized state or is using a non-standard character size.
466     /// Setting a baud rate with `set_char_size()` should initialize the character size to a
467     /// supported value.
data_bits(&self) -> Result<DataBits>468     fn data_bits(&self) -> Result<DataBits>;
469 
470     /// Returns the flow control mode.
471     ///
472     /// This function returns `None` if the flow control mode could not be determined. This may
473     /// occur if the hardware is in an uninitialized state or is using an unsupported flow control
474     /// mode. Setting a flow control mode with `set_flow_control()` should initialize the flow
475     /// control mode to a supported value.
flow_control(&self) -> Result<FlowControl>476     fn flow_control(&self) -> Result<FlowControl>;
477 
478     /// Returns the parity-checking mode.
479     ///
480     /// This function returns `None` if the parity mode could not be determined. This may occur if
481     /// the hardware is in an uninitialized state or is using a non-standard parity mode. Setting
482     /// a parity mode with `set_parity()` should initialize the parity mode to a supported value.
parity(&self) -> Result<Parity>483     fn parity(&self) -> Result<Parity>;
484 
485     /// Returns the number of stop bits.
486     ///
487     /// This function returns `None` if the number of stop bits could not be determined. This may
488     /// occur if the hardware is in an uninitialized state or is using an unsupported stop bit
489     /// configuration. Setting the number of stop bits with `set_stop-bits()` should initialize the
490     /// stop bits to a supported value.
stop_bits(&self) -> Result<StopBits>491     fn stop_bits(&self) -> Result<StopBits>;
492 
493     /// Returns the current timeout.
timeout(&self) -> Duration494     fn timeout(&self) -> Duration;
495 
496     // Port settings setters
497 
498     /// Sets the baud rate.
499     ///
500     /// ## Errors
501     ///
502     /// If the implementation does not support the requested baud rate, this function may return an
503     /// `InvalidInput` error. Even if the baud rate is accepted by `set_baud_rate()`, it may not be
504     /// supported by the underlying hardware.
set_baud_rate(&mut self, baud_rate: u32) -> Result<()>505     fn set_baud_rate(&mut self, baud_rate: u32) -> Result<()>;
506 
507     /// Sets the character size.
set_data_bits(&mut self, data_bits: DataBits) -> Result<()>508     fn set_data_bits(&mut self, data_bits: DataBits) -> Result<()>;
509 
510     /// Sets the flow control mode.
set_flow_control(&mut self, flow_control: FlowControl) -> Result<()>511     fn set_flow_control(&mut self, flow_control: FlowControl) -> Result<()>;
512 
513     /// Sets the parity-checking mode.
set_parity(&mut self, parity: Parity) -> Result<()>514     fn set_parity(&mut self, parity: Parity) -> Result<()>;
515 
516     /// Sets the number of stop bits.
set_stop_bits(&mut self, stop_bits: StopBits) -> Result<()>517     fn set_stop_bits(&mut self, stop_bits: StopBits) -> Result<()>;
518 
519     /// Sets the timeout for future I/O operations.
520     ///
521     /// <div class="warning">
522     ///
523     /// The accuracy is limited by the underlying platform's capabilities. Longer timeouts will be
524     /// clamped to the maximum supported value which is expected to be in the magnitude of a few
525     /// days.
526     ///
527     /// </div>
set_timeout(&mut self, timeout: Duration) -> Result<()>528     fn set_timeout(&mut self, timeout: Duration) -> Result<()>;
529 
530     // Functions for setting non-data control signal pins
531 
532     /// Sets the state of the RTS (Request To Send) control signal.
533     ///
534     /// Setting a value of `true` asserts the RTS control signal. `false` clears the signal.
535     ///
536     /// ## Errors
537     ///
538     /// This function returns an error if the RTS control signal could not be set to the desired
539     /// state on the underlying hardware:
540     ///
541     /// * `NoDevice` if the device was disconnected.
542     /// * `Io` for any other type of I/O error.
write_request_to_send(&mut self, level: bool) -> Result<()>543     fn write_request_to_send(&mut self, level: bool) -> Result<()>;
544 
545     /// Writes to the Data Terminal Ready pin
546     ///
547     /// Setting a value of `true` asserts the DTR control signal. `false` clears the signal.
548     ///
549     /// ## Errors
550     ///
551     /// This function returns an error if the DTR control signal could not be set to the desired
552     /// state on the underlying hardware:
553     ///
554     /// * `NoDevice` if the device was disconnected.
555     /// * `Io` for any other type of I/O error.
write_data_terminal_ready(&mut self, level: bool) -> Result<()>556     fn write_data_terminal_ready(&mut self, level: bool) -> Result<()>;
557 
558     // Functions for reading additional pins
559 
560     /// Reads the state of the CTS (Clear To Send) control signal.
561     ///
562     /// This function returns a boolean that indicates whether the CTS control signal is asserted.
563     ///
564     /// ## Errors
565     ///
566     /// This function returns an error if the state of the CTS control signal could not be read
567     /// from the underlying hardware:
568     ///
569     /// * `NoDevice` if the device was disconnected.
570     /// * `Io` for any other type of I/O error.
read_clear_to_send(&mut self) -> Result<bool>571     fn read_clear_to_send(&mut self) -> Result<bool>;
572 
573     /// Reads the state of the Data Set Ready control signal.
574     ///
575     /// This function returns a boolean that indicates whether the DSR control signal is asserted.
576     ///
577     /// ## Errors
578     ///
579     /// This function returns an error if the state of the DSR control signal could not be read
580     /// from the underlying hardware:
581     ///
582     /// * `NoDevice` if the device was disconnected.
583     /// * `Io` for any other type of I/O error.
read_data_set_ready(&mut self) -> Result<bool>584     fn read_data_set_ready(&mut self) -> Result<bool>;
585 
586     /// Reads the state of the Ring Indicator control signal.
587     ///
588     /// This function returns a boolean that indicates whether the RI control signal is asserted.
589     ///
590     /// ## Errors
591     ///
592     /// This function returns an error if the state of the RI control signal could not be read from
593     /// the underlying hardware:
594     ///
595     /// * `NoDevice` if the device was disconnected.
596     /// * `Io` for any other type of I/O error.
read_ring_indicator(&mut self) -> Result<bool>597     fn read_ring_indicator(&mut self) -> Result<bool>;
598 
599     /// Reads the state of the Carrier Detect control signal.
600     ///
601     /// This function returns a boolean that indicates whether the CD control signal is asserted.
602     ///
603     /// ## Errors
604     ///
605     /// This function returns an error if the state of the CD control signal could not be read from
606     /// the underlying hardware:
607     ///
608     /// * `NoDevice` if the device was disconnected.
609     /// * `Io` for any other type of I/O error.
read_carrier_detect(&mut self) -> Result<bool>610     fn read_carrier_detect(&mut self) -> Result<bool>;
611 
612     /// Gets the number of bytes available to be read from the input buffer.
613     ///
614     /// # Errors
615     ///
616     /// This function may return the following errors:
617     ///
618     /// * `NoDevice` if the device was disconnected.
619     /// * `Io` for any other type of I/O error.
bytes_to_read(&self) -> Result<u32>620     fn bytes_to_read(&self) -> Result<u32>;
621 
622     /// Get the number of bytes written to the output buffer, awaiting transmission.
623     ///
624     /// # Errors
625     ///
626     /// This function may return the following errors:
627     ///
628     /// * `NoDevice` if the device was disconnected.
629     /// * `Io` for any other type of I/O error.
bytes_to_write(&self) -> Result<u32>630     fn bytes_to_write(&self) -> Result<u32>;
631 
632     /// Discards all bytes from the serial driver's input buffer and/or output buffer.
633     ///
634     /// # Errors
635     ///
636     /// This function may return the following errors:
637     ///
638     /// * `NoDevice` if the device was disconnected.
639     /// * `Io` for any other type of I/O error.
clear(&self, buffer_to_clear: ClearBuffer) -> Result<()>640     fn clear(&self, buffer_to_clear: ClearBuffer) -> Result<()>;
641 
642     // Misc methods
643 
644     /// Attempts to clone the `SerialPort`. This allow you to write and read simultaneously from the
645     /// same serial connection. Please note that if you want a real asynchronous serial port you
646     /// should look at [mio-serial](https://crates.io/crates/mio-serial) or
647     /// [tokio-serial](https://crates.io/crates/tokio-serial).
648     ///
649     /// Also, you must be very careful when changing the settings of a cloned `SerialPort` : since
650     /// the settings are cached on a per object basis, trying to modify them from two different
651     /// objects can cause some nasty behavior.
652     ///
653     /// # Errors
654     ///
655     /// This function returns an error if the serial port couldn't be cloned.
try_clone(&self) -> Result<Box<dyn SerialPort>>656     fn try_clone(&self) -> Result<Box<dyn SerialPort>>;
657 
658     /// Start transmitting a break
set_break(&self) -> Result<()>659     fn set_break(&self) -> Result<()>;
660 
661     /// Stop transmitting a break
clear_break(&self) -> Result<()>662     fn clear_break(&self) -> Result<()>;
663 }
664 
665 impl<T: SerialPort> SerialPort for &mut T {
name(&self) -> Option<String>666     fn name(&self) -> Option<String> {
667         (**self).name()
668     }
669 
baud_rate(&self) -> Result<u32>670     fn baud_rate(&self) -> Result<u32> {
671         (**self).baud_rate()
672     }
673 
data_bits(&self) -> Result<DataBits>674     fn data_bits(&self) -> Result<DataBits> {
675         (**self).data_bits()
676     }
677 
flow_control(&self) -> Result<FlowControl>678     fn flow_control(&self) -> Result<FlowControl> {
679         (**self).flow_control()
680     }
681 
parity(&self) -> Result<Parity>682     fn parity(&self) -> Result<Parity> {
683         (**self).parity()
684     }
685 
stop_bits(&self) -> Result<StopBits>686     fn stop_bits(&self) -> Result<StopBits> {
687         (**self).stop_bits()
688     }
689 
timeout(&self) -> Duration690     fn timeout(&self) -> Duration {
691         (**self).timeout()
692     }
693 
set_baud_rate(&mut self, baud_rate: u32) -> Result<()>694     fn set_baud_rate(&mut self, baud_rate: u32) -> Result<()> {
695         (**self).set_baud_rate(baud_rate)
696     }
697 
set_data_bits(&mut self, data_bits: DataBits) -> Result<()>698     fn set_data_bits(&mut self, data_bits: DataBits) -> Result<()> {
699         (**self).set_data_bits(data_bits)
700     }
701 
set_flow_control(&mut self, flow_control: FlowControl) -> Result<()>702     fn set_flow_control(&mut self, flow_control: FlowControl) -> Result<()> {
703         (**self).set_flow_control(flow_control)
704     }
705 
set_parity(&mut self, parity: Parity) -> Result<()>706     fn set_parity(&mut self, parity: Parity) -> Result<()> {
707         (**self).set_parity(parity)
708     }
709 
set_stop_bits(&mut self, stop_bits: StopBits) -> Result<()>710     fn set_stop_bits(&mut self, stop_bits: StopBits) -> Result<()> {
711         (**self).set_stop_bits(stop_bits)
712     }
713 
set_timeout(&mut self, timeout: Duration) -> Result<()>714     fn set_timeout(&mut self, timeout: Duration) -> Result<()> {
715         (**self).set_timeout(timeout)
716     }
717 
write_request_to_send(&mut self, level: bool) -> Result<()>718     fn write_request_to_send(&mut self, level: bool) -> Result<()> {
719         (**self).write_request_to_send(level)
720     }
721 
write_data_terminal_ready(&mut self, level: bool) -> Result<()>722     fn write_data_terminal_ready(&mut self, level: bool) -> Result<()> {
723         (**self).write_data_terminal_ready(level)
724     }
725 
read_clear_to_send(&mut self) -> Result<bool>726     fn read_clear_to_send(&mut self) -> Result<bool> {
727         (**self).read_clear_to_send()
728     }
729 
read_data_set_ready(&mut self) -> Result<bool>730     fn read_data_set_ready(&mut self) -> Result<bool> {
731         (**self).read_data_set_ready()
732     }
733 
read_ring_indicator(&mut self) -> Result<bool>734     fn read_ring_indicator(&mut self) -> Result<bool> {
735         (**self).read_ring_indicator()
736     }
737 
read_carrier_detect(&mut self) -> Result<bool>738     fn read_carrier_detect(&mut self) -> Result<bool> {
739         (**self).read_carrier_detect()
740     }
741 
bytes_to_read(&self) -> Result<u32>742     fn bytes_to_read(&self) -> Result<u32> {
743         (**self).bytes_to_read()
744     }
745 
bytes_to_write(&self) -> Result<u32>746     fn bytes_to_write(&self) -> Result<u32> {
747         (**self).bytes_to_write()
748     }
749 
clear(&self, buffer_to_clear: ClearBuffer) -> Result<()>750     fn clear(&self, buffer_to_clear: ClearBuffer) -> Result<()> {
751         (**self).clear(buffer_to_clear)
752     }
753 
try_clone(&self) -> Result<Box<dyn SerialPort>>754     fn try_clone(&self) -> Result<Box<dyn SerialPort>> {
755         (**self).try_clone()
756     }
757 
set_break(&self) -> Result<()>758     fn set_break(&self) -> Result<()> {
759         (**self).set_break()
760     }
761 
clear_break(&self) -> Result<()>762     fn clear_break(&self) -> Result<()> {
763         (**self).clear_break()
764     }
765 }
766 
767 impl fmt::Debug for dyn SerialPort {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result768     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
769         write!(f, "SerialPort ( ")?;
770 
771         if let Some(n) = self.name().as_ref() {
772             write!(f, "name: {} ", n)?;
773         };
774         if let Ok(b) = self.baud_rate().as_ref() {
775             write!(f, "baud_rate: {} ", b)?;
776         };
777         if let Ok(b) = self.data_bits().as_ref() {
778             write!(f, "data_bits: {} ", b)?;
779         };
780         if let Ok(c) = self.flow_control().as_ref() {
781             write!(f, "flow_control: {} ", c)?;
782         }
783         if let Ok(p) = self.parity().as_ref() {
784             write!(f, "parity: {} ", p)?;
785         }
786         if let Ok(s) = self.stop_bits().as_ref() {
787             write!(f, "stop_bits: {} ", s)?;
788         }
789 
790         write!(f, ")")
791     }
792 }
793 
794 /// Contains all possible USB information about a `SerialPort`
795 #[derive(Debug, Clone, PartialEq, Eq)]
796 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
797 pub struct UsbPortInfo {
798     /// Vendor ID
799     pub vid: u16,
800     /// Product ID
801     pub pid: u16,
802     /// Serial number (arbitrary string)
803     pub serial_number: Option<String>,
804     /// Manufacturer (arbitrary string)
805     pub manufacturer: Option<String>,
806     /// Product name (arbitrary string)
807     pub product: Option<String>,
808     /// The interface index of the USB serial port. This can be either the interface number of
809     /// the communication interface (as is the case on Windows and Linux) or the data
810     /// interface (as is the case on macOS), so you should recognize both interface numbers.
811     #[cfg(feature = "usbportinfo-interface")]
812     pub interface: Option<u8>,
813 }
814 
815 /// The physical type of a `SerialPort`
816 #[derive(Debug, Clone, PartialEq, Eq)]
817 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
818 pub enum SerialPortType {
819     /// The serial port is connected via USB
820     UsbPort(UsbPortInfo),
821     /// The serial port is connected via PCI (permanent port)
822     PciPort,
823     /// The serial port is connected via Bluetooth
824     BluetoothPort,
825     /// It can't be determined how the serial port is connected
826     Unknown,
827 }
828 
829 /// A device-independent implementation of serial port information
830 #[derive(Debug, Clone, PartialEq, Eq)]
831 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
832 pub struct SerialPortInfo {
833     /// The short name of the serial port
834     pub port_name: String,
835     /// The hardware device type that exposes this port
836     pub port_type: SerialPortType,
837 }
838 
839 /// Construct a builder of `SerialPort` objects
840 ///
841 /// `SerialPort` objects are built using the Builder pattern through the `new` function. The
842 /// resultant `SerialPortBuilder` object can be copied, reconfigured, and saved making working with
843 /// multiple serial ports a little easier.
844 ///
845 /// To open a new serial port:
846 /// ```no_run
847 /// serialport::new("/dev/ttyUSB0", 9600).open().expect("Failed to open port");
848 /// ```
new<'a>(path: impl Into<std::borrow::Cow<'a, str>>, baud_rate: u32) -> SerialPortBuilder849 pub fn new<'a>(path: impl Into<std::borrow::Cow<'a, str>>, baud_rate: u32) -> SerialPortBuilder {
850     SerialPortBuilder {
851         path: path.into().into_owned(),
852         baud_rate,
853         data_bits: DataBits::Eight,
854         flow_control: FlowControl::None,
855         parity: Parity::None,
856         stop_bits: StopBits::One,
857         timeout: Duration::from_millis(0),
858         // By default, set DTR when opening the device. There are USB devices performing "wait for
859         // DTR" before sending any data and users stumbled over this multiple times (see issues #29
860         // and #204). We are expecting little to no negative consequences from setting DTR by
861         // default but less hassle for users.
862         dtr_on_open: Some(true),
863     }
864 }
865 
866 /// Returns a list of all serial ports on system
867 ///
868 /// It is not guaranteed that these ports exist or are available even if they're
869 /// returned by this function.
available_ports() -> Result<Vec<SerialPortInfo>>870 pub fn available_ports() -> Result<Vec<SerialPortInfo>> {
871     #[cfg(unix)]
872     return crate::posix::available_ports();
873 
874     #[cfg(windows)]
875     return crate::windows::available_ports();
876 
877     #[cfg(not(any(unix, windows)))]
878     Err(Error::new(
879         ErrorKind::Unknown,
880         "available_ports() not implemented for platform",
881     ))
882 }
883