@@ -23,7 +23,27 @@ pub fn get_serial_port(matches: &ConnectArgs, config: &Config) -> Result<String,
23
23
} else if let Some ( serial) = & config. connection . serial {
24
24
Ok ( serial. to_owned ( ) )
25
25
} else if let Ok ( ports) = detect_usb_serial_ports ( ) {
26
- select_serial_port ( ports, & config. usb_device )
26
+ let ( port, matches) = select_serial_port ( ports, config) ?;
27
+ match port. port_type {
28
+ SerialPortType :: UsbPort ( usb_info) if !matches => {
29
+ if Confirm :: with_theme ( & ColorfulTheme :: default ( ) )
30
+ . with_prompt ( "Remember this serial port for future use?" )
31
+ . interact_opt ( ) ?
32
+ . unwrap_or_default ( )
33
+ {
34
+ if let Err ( e) = config. save_with ( |config| {
35
+ config. usb_device . push ( UsbDevice {
36
+ vid : usb_info. vid ,
37
+ pid : usb_info. pid ,
38
+ } )
39
+ } ) {
40
+ eprintln ! ( "Failed to save config {:#}" , e) ;
41
+ }
42
+ }
43
+ }
44
+ _ => { }
45
+ }
46
+ Ok ( port. port_name )
27
47
} else {
28
48
Err ( Error :: NoSerial )
29
49
}
@@ -56,10 +76,11 @@ const KNOWN_DEVICES: &[UsbDevice] = &[
56
76
57
77
fn select_serial_port (
58
78
ports : Vec < SerialPortInfo > ,
59
- configured_devices : & [ UsbDevice ] ,
60
- ) -> Result < String , Error > {
79
+ config : & Config ,
80
+ ) -> Result < ( SerialPortInfo , bool ) , Error > {
61
81
let device_matches = |info| {
62
- configured_devices
82
+ config
83
+ . usb_device
63
84
. iter ( )
64
85
. chain ( KNOWN_DEVICES . iter ( ) )
65
86
. any ( |dev| dev. matches ( info) )
@@ -97,7 +118,15 @@ fn select_serial_port(
97
118
. ok_or ( Error :: Canceled ) ?;
98
119
99
120
match ports. get ( index) {
100
- Some ( port_info) => Ok ( port_info. port_name . to_owned ( ) ) ,
121
+ Some (
122
+ port_info
123
+ @
124
+ SerialPortInfo {
125
+ port_type : SerialPortType :: UsbPort ( usb_info) ,
126
+ ..
127
+ } ,
128
+ ) => Ok ( ( port_info. clone ( ) , device_matches ( usb_info) ) ) ,
129
+ Some ( port_info) => Ok ( ( port_info. clone ( ) , false ) ) ,
101
130
None => Err ( Error :: NoSerial ) ,
102
131
}
103
132
} else if let [ port] = ports. as_slice ( ) {
@@ -108,19 +137,20 @@ fn select_serial_port(
108
137
_ => unreachable ! ( ) ,
109
138
} ;
110
139
111
- if device_matches ( port_info)
112
- || Confirm :: with_theme ( & ColorfulTheme :: default ( ) )
113
- . with_prompt ( {
114
- if let Some ( product) = & port_info. product {
115
- format ! ( "Use serial port '{}' - {}?" , port_name, product)
116
- } else {
117
- format ! ( "Use serial port '{}'?" , port_name)
118
- }
119
- } )
120
- . interact_opt ( ) ?
121
- . ok_or ( Error :: Canceled ) ?
140
+ if device_matches ( port_info) {
141
+ Ok ( ( port. clone ( ) , true ) )
142
+ } else if Confirm :: with_theme ( & ColorfulTheme :: default ( ) )
143
+ . with_prompt ( {
144
+ if let Some ( product) = & port_info. product {
145
+ format ! ( "Use serial port '{}' - {}?" , port_name, product)
146
+ } else {
147
+ format ! ( "Use serial port '{}'?" , port_name)
148
+ }
149
+ } )
150
+ . interact_opt ( ) ?
151
+ . ok_or ( Error :: Canceled ) ?
122
152
{
123
- Ok ( port_name )
153
+ Ok ( ( port . clone ( ) , false ) )
124
154
} else {
125
155
Err ( Error :: NoSerial )
126
156
}
0 commit comments