Skip to content

Commit f3b5ba4

Browse files
soiamsoNGsirhcel
authored andcommitted
Remove regex
1 parent e095439 commit f3b5ba4

File tree

2 files changed

+60
-35
lines changed

2 files changed

+60
-35
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ nix = { version = "0.26", default-features = false, features = ["fs", "ioctl", "
2222
[target.'cfg(all(target_os = "linux", not(target_env = "musl")))'.dependencies]
2323
libudev = { version = "0.3.0", optional = true }
2424
unescaper = "0.1.3"
25-
regex = "1.5.5"
2625

2726
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
2827
core-foundation-sys = "0.8.4"

src/posix/enumerate.rs

Lines changed: 60 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use cfg_if::cfg_if;
33
cfg_if! {
44
if #[cfg(all(target_os = "linux", not(target_env = "musl"), feature = "libudev"))]{
55
use std::ffi::OsStr;
6-
use regex::Regex;
76
}
87
}
98

@@ -215,41 +214,9 @@ fn port_type(d: &libudev::Device) -> Result<SerialPortType> {
215214
)
216215
}
217216

218-
// MODALIAS = usb:v303Ap1001d0101dcEFdsc02dp01ic02isc02ip00in00
219-
// v 303A (device vendor)
220-
// p 1001 (device product)
221-
// d 0101 (bcddevice)
222-
// dc EF (device class)
223-
// dsc 02 (device subclass)
224-
// dp 01 (device protocol)
225-
// ic 02 (interface class)
226-
// isc 02 (interface subclass)
227-
// ip 00 (interface protocol)
228-
// in 00 (interface number)
229-
fn parse_modalias(moda: String) -> Option<UsbPortInfo> {
230-
let re = Regex::new(concat!(
231-
r"usb:v(?P<vid>[[:xdigit:]]{4})",
232-
r"p(?P<pid>[[:xdigit:]]{4})",
233-
r".*",
234-
r"in(?P<in>[[:xdigit:]]{2})"
235-
))
236-
.unwrap();
237-
238-
let caps = re.captures(moda.as_str())?;
239-
240-
Some(UsbPortInfo {
241-
vid: u16::from_str_radix(&caps["vid"], 16).ok()?,
242-
pid: u16::from_str_radix(&caps["pid"], 16).ok()?,
243-
serial_number: None,
244-
manufacturer: None,
245-
product: None,
246-
#[cfg(feature = "usbportinfo-interface")]
247-
interface: u8::from_str_radix(&caps["in"], 16).ok(),
248-
})
249-
}
250-
251217
find_usb_interface_from_parents(d.parent())
252218
.and_then(get_modalias_from_device)
219+
.as_deref()
253220
.and_then(parse_modalias)
254221
.map_or(Ok(SerialPortType::Unknown), |port_info| {
255222
Ok(SerialPortType::UsbPort(port_info))
@@ -259,6 +226,51 @@ fn port_type(d: &libudev::Device) -> Result<SerialPortType> {
259226
}
260227
}
261228

229+
// MODALIAS = usb:v303Ap1001d0101dcEFdsc02dp01ic02isc02ip00in00
230+
// v 303A (device vendor)
231+
// p 1001 (device product)
232+
// d 0101 (bcddevice)
233+
// dc EF (device class)
234+
// dsc 02 (device subclass)
235+
// dp 01 (device protocol)
236+
// ic 02 (interface class)
237+
// isc 02 (interface subclass)
238+
// ip 00 (interface protocol)
239+
// in 00 (interface number)
240+
#[cfg(all(target_os = "linux", not(target_env = "musl"), feature = "libudev"))]
241+
fn parse_modalias(moda: &str) -> Option<UsbPortInfo> {
242+
// Find the start of the string, will start with "usb:"
243+
let mod_start = moda.find("usb:v")?;
244+
245+
// Tail to update while searching.
246+
let mut mod_tail = moda.get(mod_start + 5..)?;
247+
248+
// The next four characters should be hex values of the vendor.
249+
let vid = mod_tail.get(..4)?;
250+
mod_tail = mod_tail.get(4..)?;
251+
252+
// The next portion we care about is the device product ID.
253+
let pid_start = mod_tail.find('p')?;
254+
let pid = mod_tail.get(pid_start + 1..pid_start + 5)?;
255+
256+
Some(UsbPortInfo {
257+
vid: u16::from_str_radix(vid, 16).ok()?,
258+
pid: u16::from_str_radix(pid, 16).ok()?,
259+
serial_number: None,
260+
manufacturer: None,
261+
product: None,
262+
// Only attempt to find the interface if the feature is enabled.
263+
#[cfg(feature = "usbportinfo-interface")]
264+
interface: mod_tail.get(pid_start + 4..).and_then(|mod_tail| {
265+
mod_tail.find("in").and_then(|i_start| {
266+
mod_tail
267+
.get(i_start + 2..i_start + 4)
268+
.and_then(|interface| u8::from_str_radix(interface, 16).ok())
269+
})
270+
}),
271+
})
272+
}
273+
262274
#[cfg(any(target_os = "ios", target_os = "macos"))]
263275
fn get_parent_device_by_type(
264276
device: io_object_t,
@@ -679,3 +691,17 @@ cfg_if! {
679691
}
680692
}
681693
}
694+
695+
#[cfg(all(target_os = "linux", not(target_env = "musl"), feature = "libudev"))]
696+
#[test]
697+
fn parser_modalias() {
698+
const MODALIAS: &str = "usb:v303Ap1001d0101dcEFdsc02dp01ic02isc02ip00in0C";
699+
700+
let port_info = parse_modalias(MODALIAS).expect("parse failed");
701+
702+
assert_eq!(port_info.vid, 0x303A, "vendor parse invalid");
703+
assert_eq!(port_info.pid, 0x1001, "product parse invalid");
704+
705+
#[cfg(feature = "usbportinfo-interface")]
706+
assert_eq!(port_info.interface, Some(0x0C), "interface parse invalid");
707+
}

0 commit comments

Comments
 (0)