@@ -13,12 +13,13 @@ use crossbeam_channel::{select, Receiver, Sender};
13
13
use eframe:: egui:: { vec2, ViewportBuilder , Visuals } ;
14
14
use eframe:: { egui, icon_data} ;
15
15
use egui_plot:: PlotPoint ;
16
+ pub use gumdrop:: Options ;
16
17
use preferences:: AppInfo ;
17
18
use std:: cmp:: max;
18
19
use std:: path:: PathBuf ;
19
20
use std:: sync:: { Arc , RwLock } ;
21
+ use std:: thread;
20
22
use std:: time:: Duration ;
21
- use std:: { env, thread} ;
22
23
23
24
mod color_picker;
24
25
mod custom_highlighter;
@@ -262,13 +263,100 @@ fn main_thread(
262
263
}
263
264
}
264
265
266
+ fn parse_databits ( s : & str ) -> Result < serialport:: DataBits , String > {
267
+ let d: u8 = s
268
+ . parse ( )
269
+ . map_err ( |_e| format ! ( "databits not a number: {s}" ) ) ?;
270
+ Ok ( serialport:: DataBits :: try_from ( d) . map_err ( |_e| format ! ( "invalid databits: {s}" ) ) ?)
271
+ }
272
+
273
+ fn parse_flow ( s : & str ) -> Result < serialport:: FlowControl , String > {
274
+ match s {
275
+ "none" => Ok ( serialport:: FlowControl :: None ) ,
276
+ "soft" => Ok ( serialport:: FlowControl :: Software ) ,
277
+ "hard" => Ok ( serialport:: FlowControl :: Hardware ) ,
278
+ _ => Err ( format ! ( "invalid flow-control: {s}" ) ) ,
279
+ }
280
+ }
281
+
282
+ fn parse_stopbits ( s : & str ) -> Result < serialport:: StopBits , String > {
283
+ let d: u8 = s
284
+ . parse ( )
285
+ . map_err ( |_e| format ! ( "stopbits not a number: {s}" ) ) ?;
286
+ Ok ( serialport:: StopBits :: try_from ( d) . map_err ( |_e| format ! ( "invalid stopbits: {s}" ) ) ?)
287
+ }
288
+
289
+ fn parse_parity ( s : & str ) -> Result < serialport:: Parity , String > {
290
+ match s {
291
+ "none" => Ok ( serialport:: Parity :: None ) ,
292
+ "odd" => Ok ( serialport:: Parity :: Odd ) ,
293
+ "even" => Ok ( serialport:: Parity :: Even ) ,
294
+ _ => Err ( format ! ( "invalid parity setting: {s}" ) ) ,
295
+ }
296
+ }
297
+
298
+ #[ derive( Debug , Options ) ]
299
+ struct CliOptions {
300
+ /// Serial port device to open on startup
301
+ #[ options( free) ]
302
+ device : Option < String > ,
303
+
304
+ /// Baudrate (default=9600)
305
+ #[ options( short = "b" ) ]
306
+ baudrate : Option < u32 > ,
307
+
308
+ /// Data bits (5, 6, 7, default=8)
309
+ #[ options( short = "d" , parse( try_from_str = "parse_databits" ) ) ]
310
+ databits : Option < serialport:: DataBits > ,
311
+
312
+ /// Flow conrol (hard, soft, default=none)
313
+ #[ options( short = "f" , parse( try_from_str = "parse_flow" ) ) ]
314
+ flow : Option < serialport:: FlowControl > ,
315
+
316
+ /// Stop bits (default=1, 2)
317
+ #[ options( short = "s" , parse( try_from_str = "parse_stopbits" ) ) ]
318
+ stopbits : Option < serialport:: StopBits > ,
319
+
320
+ /// Parity (odd, even, default=none)
321
+ #[ options( short = "p" , parse( try_from_str = "parse_parity" ) ) ]
322
+ parity : Option < serialport:: Parity > ,
323
+
324
+ /// Load data from a file instead of a serial port
325
+ #[ options( short = "F" ) ]
326
+ file : Option < std:: path:: PathBuf > ,
327
+
328
+ help : bool ,
329
+ }
330
+
265
331
fn main ( ) {
266
332
egui_logger:: builder ( ) . init ( ) . unwrap ( ) ;
267
333
334
+ let args = CliOptions :: parse_args_default_or_exit ( ) ;
335
+
268
336
let gui_settings = load_gui_settings ( ) ;
269
337
let saved_serial_device_configs = load_serial_settings ( ) ;
270
338
271
- let device_lock = Arc :: new ( RwLock :: new ( Device :: default ( ) ) ) ;
339
+ let mut device = Device :: default ( ) ;
340
+ if let Some ( name) = args. device {
341
+ device. name = name;
342
+ }
343
+ if let Some ( baudrate) = args. baudrate {
344
+ device. baud_rate = baudrate;
345
+ }
346
+ if let Some ( databits) = args. databits {
347
+ device. data_bits = databits;
348
+ }
349
+ if let Some ( flow) = args. flow {
350
+ device. flow_control = flow;
351
+ }
352
+ if let Some ( stopbits) = args. stopbits {
353
+ device. stop_bits = stopbits;
354
+ }
355
+ if let Some ( parity) = args. parity {
356
+ device. parity = parity;
357
+ }
358
+
359
+ let device_lock = Arc :: new ( RwLock :: new ( device) ) ;
272
360
let devices_lock = Arc :: new ( RwLock :: new ( vec ! [ gui_settings. device. clone( ) ] ) ) ;
273
361
let data_lock = Arc :: new ( RwLock :: new ( GuiOutputDataContainer :: default ( ) ) ) ;
274
362
let connected_lock = Arc :: new ( RwLock :: new ( false ) ) ;
@@ -319,11 +407,8 @@ fn main() {
319
407
) ;
320
408
} ) ;
321
409
322
- let args: Vec < String > = env:: args ( ) . collect ( ) ;
323
- if args. len ( ) > 1 {
324
- load_tx
325
- . send ( PathBuf :: from ( & args[ 1 ] ) )
326
- . expect ( "failed to send file" ) ;
410
+ if let Some ( file) = args. file {
411
+ load_tx. send ( file) . expect ( "failed to send file" ) ;
327
412
}
328
413
329
414
let options = eframe:: NativeOptions {
0 commit comments