serial_enumerate/
lib.rs

1
2//! This crate provides an easy way to enumerate serial ports.
3//!
4//! ```
5//! for device in serial_enumerate::enumerate_serial_ports().unwrap() {
6//!     println!("{}", device);
7//! }
8//! ```
9//!
10
11#[macro_use]
12extern crate error_chain;
13
14#[cfg(target_os = "windows")]
15extern crate winreg;
16
17pub mod errors;
18
19use errors::*;
20
21/// Lists the serial ports that are connected to the computer
22#[cfg(target_os = "windows")]
23pub fn enumerate_serial_ports() -> Result<Vec<String>> {
24    use winreg::RegKey;
25    use winreg::enums::{HKEY_LOCAL_MACHINE, KEY_READ};
26
27    let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
28    let serial_device_map = hklm.open_subkey_with_flags("HARDWARE\\DEVICEMAP\\SERIALCOMM", KEY_READ)
29        .chain_err(|| "Unable to open registry")?;
30
31    let mut devices = vec![];
32    for entry in serial_device_map.enum_values() {
33        let name = entry.chain_err(|| "The registry entry could not be retrieved")?.0;
34        let device = serial_device_map.get_value(name)
35            .chain_err(|| "The registry entry's value could not be retrieved")?;
36        devices.push(device);
37    }
38
39    Ok(devices)
40}
41
42/// Lists the serial ports that are connected to the computer
43#[cfg(target_os = "linux")]
44pub fn enumerate_serial_ports() -> Result<Vec<String>> {
45    use std::fs;
46    let device_directory = fs::read_dir("/dev/serial/by-id").chain_err(|| "/dev/serial not found")?;
47
48    let mut devices = vec![];
49    for entry in device_directory {
50        let path = entry.chain_err(|| "Directory entry could not be read")?
51            .path()
52            .canonicalize()
53            .chain_err(|| "Could not get absolute path of serial port")?;
54        let path_string = match path.to_str() {
55            Some(path_string) => path_string.into(),
56            None => return Err(Error::from("Path could not be converted to string")),
57        };
58        devices.push(path_string);
59    }
60    Ok(devices)
61}