1
- use super :: config:: Config ;
2
1
use crossterm:: style:: Stylize ;
3
2
use dialoguer:: { theme:: ColorfulTheme , Confirm , Select } ;
4
3
use miette:: { IntoDiagnostic , Result } ;
5
4
use serialport:: { available_ports, SerialPortInfo , SerialPortType } ;
6
5
7
- use super :: clap:: ConnectArgs ;
8
- use crate :: cli:: config:: UsbDevice ;
9
- use crate :: error:: Error ;
6
+ use super :: { clap:: ConnectArgs , config:: Config } ;
7
+ use crate :: { cli:: config:: UsbDevice , error:: Error } ;
10
8
11
- pub fn get_serial_port ( matches : & ConnectArgs , config : & Config ) -> Result < String , Error > {
9
+ pub fn get_serial_port_info (
10
+ matches : & ConnectArgs ,
11
+ config : & Config ,
12
+ ) -> Result < SerialPortInfo , Error > {
12
13
// A serial port should be specified either as a command-line argument or in a
13
14
// configuration file. In the case that both have been provided the command-line
14
15
// argument takes precedence.
15
16
//
16
17
// Users may optionally specify the device's VID and PID in the configuration
17
- // file. If no VID/PID have been provided, the user will always be prompted to
18
- // select a serial device. If some VID/PID have been provided the user will be
19
- // prompted to select a serial device, unless there is only one found and its
20
- // VID/PID matches the configured values.
21
- if let Some ( serial) = & matches. serial {
22
- Ok ( serial. to_owned ( ) )
18
+ // file. If no VID/PID has been provided, the user will always be prompted to
19
+ // select a serial port. If some VID and PID were provided then the user will
20
+ // also be prompted to select a port, unless there is only one found and its VID
21
+ // and PID match the configured values.
22
+ let ports = detect_usb_serial_ports ( ) . unwrap_or_default ( ) ;
23
+
24
+ let maybe_port = if let Some ( serial) = & matches. serial {
25
+ find_serial_port ( & ports, serial. to_owned ( ) )
23
26
} else if let Some ( serial) = & config. connection . serial {
24
- Ok ( serial. to_owned ( ) )
25
- } else if let Ok ( ports) = detect_usb_serial_ports ( ) {
27
+ find_serial_port ( & ports , serial. to_owned ( ) )
28
+ } else if ! ports. is_empty ( ) {
26
29
let ( port, matches) = select_serial_port ( ports, config) ?;
27
- match port. port_type {
30
+ match & port. port_type {
28
31
SerialPortType :: UsbPort ( usb_info) if !matches => {
29
32
if Confirm :: with_theme ( & ColorfulTheme :: default ( ) )
30
33
. with_prompt ( "Remember this serial port for future use?" )
@@ -43,20 +46,39 @@ pub fn get_serial_port(matches: &ConnectArgs, config: &Config) -> Result<String,
43
46
}
44
47
_ => { }
45
48
}
46
- Ok ( port. port_name )
49
+
50
+ Some ( port)
51
+ } else {
52
+ None
53
+ } ;
54
+
55
+ if let Some ( port_info) = maybe_port {
56
+ Ok ( port_info)
47
57
} else {
48
58
Err ( Error :: NoSerial )
49
59
}
50
60
}
51
61
52
- /// serialport's autodetect doesn't provide any port information when using musl linux
53
- /// we can do some manual parsing of sysfs to get the relevant bits without udev
62
+ /// Given a vector of `SerialPortInfo` structs, attempt to find and return one
63
+ /// whose `port_name` field matches the provided `name` argument.
64
+ fn find_serial_port ( ports : & [ SerialPortInfo ] , name : String ) -> Option < SerialPortInfo > {
65
+ ports
66
+ . iter ( )
67
+ . find ( |port| port. port_name == name)
68
+ . map ( |port| port. to_owned ( ) )
69
+ }
70
+
71
+ /// serialport's autodetect doesn't provide any port information when using musl
72
+ /// linux we can do some manual parsing of sysfs to get the relevant bits
73
+ /// without udev
54
74
#[ cfg( all( target_os = "linux" , target_env = "musl" ) ) ]
55
75
fn detect_usb_serial_ports ( ) -> Result < Vec < SerialPortInfo > > {
76
+ use std:: {
77
+ fs:: { read_link, read_to_string} ,
78
+ path:: PathBuf ,
79
+ } ;
80
+
56
81
use serialport:: UsbPortInfo ;
57
- use std:: fs:: read_link;
58
- use std:: fs:: read_to_string;
59
- use std:: path:: PathBuf ;
60
82
61
83
let ports = available_ports ( ) . into_diagnostic ( ) ?;
62
84
let ports = ports
0 commit comments