@@ -13,12 +13,13 @@ use crossbeam_channel::{select, Receiver, Sender};
1313use  eframe:: egui:: { vec2,  ViewportBuilder ,  Visuals } ; 
1414use  eframe:: { egui,  icon_data} ; 
1515use  egui_plot:: PlotPoint ; 
16+ pub  use  gumdrop:: Options ; 
1617use  preferences:: AppInfo ; 
1718use  std:: cmp:: max; 
1819use  std:: path:: PathBuf ; 
1920use  std:: sync:: { Arc ,  RwLock } ; 
21+ use  std:: thread; 
2022use  std:: time:: Duration ; 
21- use  std:: { env,  thread} ; 
2223
2324mod  color_picker; 
2425mod  custom_highlighter; 
@@ -262,13 +263,100 @@ fn main_thread(
262263    } 
263264} 
264265
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+ 
265331fn  main ( )  { 
266332    egui_logger:: builder ( ) . init ( ) . unwrap ( ) ; 
267333
334+     let  args = CliOptions :: parse_args_default_or_exit ( ) ; 
335+ 
268336    let  gui_settings = load_gui_settings ( ) ; 
269337    let  saved_serial_device_configs = load_serial_settings ( ) ; 
270338
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) ) ; 
272360    let  devices_lock = Arc :: new ( RwLock :: new ( vec ! [ gui_settings. device. clone( ) ] ) ) ; 
273361    let  data_lock = Arc :: new ( RwLock :: new ( GuiOutputDataContainer :: default ( ) ) ) ; 
274362    let  connected_lock = Arc :: new ( RwLock :: new ( false ) ) ; 
@@ -319,11 +407,8 @@ fn main() {
319407        ) ; 
320408    } ) ; 
321409
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" ) ; 
327412    } 
328413
329414    let  options = eframe:: NativeOptions  { 
0 commit comments