#![deny(
missing_docs,
missing_debug_implementations,
missing_copy_implementations,
unused
)]
#![doc(test(attr(allow(unused_must_use))))]
use std::error::Error as StdError;
use std::fmt;
use std::io;
use std::path::Path;
use std::time::Duration;
mod sys;
#[cfg(any(unix, doc))]
pub mod posix;
#[cfg(any(windows, doc))]
pub mod windows;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ErrorKind {
NoDevice,
InvalidInput,
Unknown,
Io(io::ErrorKind),
}
#[derive(Debug)]
pub struct Error {
pub kind: ErrorKind,
pub description: String,
}
impl Error {
pub fn new<T: Into<String>>(kind: ErrorKind, description: T) -> Self {
Error {
kind,
description: description.into(),
}
}
pub fn kind(&self) -> ErrorKind {
self.kind
}
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> std::result::Result<(), fmt::Error> {
fmt.write_str(&self.description)
}
}
impl StdError for Error {
fn description(&self) -> &str {
&self.description
}
}
impl From<io::Error> for Error {
fn from(io_error: io::Error) -> Error {
Error::new(ErrorKind::Io(io_error.kind()), format!("{}", io_error))
}
}
impl From<Error> for io::Error {
fn from(error: Error) -> io::Error {
let kind = match error.kind {
ErrorKind::NoDevice => io::ErrorKind::NotFound,
ErrorKind::InvalidInput => io::ErrorKind::InvalidInput,
ErrorKind::Unknown => io::ErrorKind::Other,
ErrorKind::Io(kind) => kind,
};
io::Error::new(kind, error.description)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum DataBits {
Five,
Six,
Seven,
Eight,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Parity {
None,
Odd,
Even,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum StopBits {
One,
Two,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum FlowControl {
None,
Software,
Hardware,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ClearBuffer {
Input,
Output,
All,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct SerialPortBuilder {
baud_rate: u32,
data_bits: DataBits,
flow_control: FlowControl,
parity: Parity,
stop_bits: StopBits,
read_timeout: Option<Duration>,
write_timeout: Option<Duration>,
}
impl SerialPortBuilder {
pub fn new() -> Self {
Default::default()
}
pub fn baud_rate(mut self, baud_rate: u32) -> Self {
self.baud_rate = baud_rate;
self
}
pub fn data_bits(mut self, data_bits: DataBits) -> Self {
self.data_bits = data_bits;
self
}
pub fn flow_control(mut self, flow_control: FlowControl) -> Self {
self.flow_control = flow_control;
self
}
pub fn parity(mut self, parity: Parity) -> Self {
self.parity = parity;
self
}
pub fn stop_bits(mut self, stop_bits: StopBits) -> Self {
self.stop_bits = stop_bits;
self
}
pub fn read_timeout(mut self, read_timeout: Option<Duration>) -> Self {
self.read_timeout = read_timeout;
self
}
pub fn write_timeout(mut self, write_timeout: Option<Duration>) -> Self {
self.write_timeout = write_timeout;
self
}
pub fn open(self, path: impl AsRef<Path>) -> Result<SerialPort> {
Ok(SerialPort(sys::SerialPort::open(self, path)?))
}
}
impl Default for SerialPortBuilder {
fn default() -> Self {
SerialPortBuilder {
baud_rate: 9600,
data_bits: DataBits::Eight,
flow_control: FlowControl::None,
parity: Parity::None,
stop_bits: StopBits::One,
read_timeout: None,
write_timeout: None,
}
}
}
#[derive(Debug)]
pub struct SerialPort(sys::SerialPort);
impl SerialPort {
pub fn builder() -> SerialPortBuilder {
Default::default()
}
pub fn name(&self) -> Option<&str> {
self.0.name()
}
pub fn baud_rate(&self) -> Result<u32> {
self.0.baud_rate()
}
pub fn data_bits(&self) -> Result<DataBits> {
self.0.data_bits()
}
pub fn flow_control(&self) -> Result<FlowControl> {
self.0.flow_control()
}
pub fn parity(&self) -> Result<Parity> {
self.0.parity()
}
pub fn stop_bits(&self) -> Result<StopBits> {
self.0.stop_bits()
}
pub fn read_timeout(&self) -> Option<Duration> {
self.0.read_timeout()
}
pub fn write_timeout(&self) -> Option<Duration> {
self.0.write_timeout()
}
pub fn set_baud_rate(&mut self, baud_rate: u32) -> Result<()> {
self.0.set_baud_rate(baud_rate)
}
pub fn set_data_bits(&mut self, data_bits: DataBits) -> Result<()> {
self.0.set_data_bits(data_bits)
}
pub fn set_flow_control(&mut self, flow_control: FlowControl) -> Result<()> {
self.0.set_flow_control(flow_control)
}
pub fn set_parity(&mut self, parity: Parity) -> Result<()> {
self.0.set_parity(parity)
}
pub fn set_stop_bits(&mut self, stop_bits: StopBits) -> Result<()> {
self.0.set_stop_bits(stop_bits)
}
pub fn set_read_timeout(&mut self, read_timeout: Option<Duration>) -> Result<()> {
self.0.set_read_timeout(read_timeout)
}
pub fn set_write_timeout(&mut self, write_timeout: Option<Duration>) -> Result<()> {
self.0.set_write_timeout(write_timeout)
}
pub fn write_request_to_send(&mut self, level: bool) -> Result<()> {
self.0.write_request_to_send(level)
}
pub fn write_data_terminal_ready(&mut self, level: bool) -> Result<()> {
self.0.write_data_terminal_ready(level)
}
pub fn read_clear_to_send(&mut self) -> Result<bool> {
self.0.read_clear_to_send()
}
pub fn read_data_set_ready(&mut self) -> Result<bool> {
self.0.read_data_set_ready()
}
pub fn read_ring_indicator(&mut self) -> Result<bool> {
self.0.read_ring_indicator()
}
pub fn read_carrier_detect(&mut self) -> Result<bool> {
self.0.read_carrier_detect()
}
pub fn bytes_to_read(&self) -> Result<u32> {
self.0.bytes_to_read()
}
pub fn bytes_to_write(&self) -> Result<u32> {
self.0.bytes_to_write()
}
pub fn clear(&self, buffer_to_clear: ClearBuffer) -> Result<()> {
self.0.clear(buffer_to_clear)
}
pub fn try_clone(&self) -> Result<Self> {
Ok(SerialPort(self.0.try_clone()?))
}
pub fn set_break(&self) -> Result<()> {
self.0.set_break()
}
pub fn clear_break(&self) -> Result<()> {
self.0.clear_break()
}
}
impl io::Read for SerialPort {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
io::Read::read(&mut &self.0, buf)
}
}
impl io::Read for &SerialPort {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
io::Read::read(&mut &self.0, buf)
}
}
impl io::Write for SerialPort {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
io::Write::write(&mut &self.0, buf)
}
fn flush(&mut self) -> io::Result<()> {
io::Write::flush(&mut &self.0)
}
}
impl io::Write for &SerialPort {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
io::Write::write(&mut &self.0, buf)
}
fn flush(&mut self) -> io::Result<()> {
io::Write::flush(&mut &self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UsbPortInfo {
pub vid: u16,
pub pid: u16,
pub serial_number: Option<String>,
pub manufacturer: Option<String>,
pub product: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SerialPortType {
UsbPort(UsbPortInfo),
PciPort,
BluetoothPort,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SerialPortInfo {
pub port_name: String,
pub port_type: SerialPortType,
}
pub fn available_ports() -> Result<Vec<SerialPortInfo>> {
sys::available_ports()
}