@@ -564,19 +564,58 @@ fn string_to_combo(arg: &str) -> Option<&str> {
564564}
565565
566566fn string_to_baud ( arg : & str ) -> Option < AllFlags < ' _ > > {
567- // BSDs use a u32 for the baud rate, so any decimal number applies.
568- #[ cfg( any(
569- target_os = "freebsd" ,
570- target_os = "dragonfly" ,
571- target_os = "ios" ,
572- target_os = "macos" ,
573- target_os = "netbsd" ,
574- target_os = "openbsd"
575- ) ) ]
576- if let Ok ( n) = arg. parse :: < u32 > ( ) {
577- return Some ( AllFlags :: Baud ( n) ) ;
567+ // Normalize the input: trim whitespace and leading '+'
568+ let normalized = arg. trim ( ) . trim_start_matches ( '+' ) ;
569+
570+ // Try to parse as a floating point number for rounding
571+ if let Ok ( f) = normalized. parse :: < f64 > ( ) {
572+ let rounded = f. round ( ) as u32 ;
573+
574+ // BSDs use a u32 for the baud rate, so any decimal number applies.
575+ #[ cfg( any(
576+ target_os = "freebsd" ,
577+ target_os = "dragonfly" ,
578+ target_os = "ios" ,
579+ target_os = "macos" ,
580+ target_os = "netbsd" ,
581+ target_os = "openbsd"
582+ ) ) ]
583+ return Some ( AllFlags :: Baud ( rounded) ) ;
584+
585+ // On other platforms, find the closest valid baud rate
586+ #[ cfg( not( any(
587+ target_os = "freebsd" ,
588+ target_os = "dragonfly" ,
589+ target_os = "ios" ,
590+ target_os = "macos" ,
591+ target_os = "netbsd" ,
592+ target_os = "openbsd"
593+ ) ) ) ]
594+ {
595+ let rounded_str = rounded. to_string ( ) ;
596+ // First try exact match
597+ for ( text, baud_rate) in BAUD_RATES {
598+ if * text == rounded_str {
599+ return Some ( AllFlags :: Baud ( * baud_rate) ) ;
600+ }
601+ }
602+ // If no exact match, find closest baud rate
603+ let mut closest: Option < ( u32 , nix:: sys:: termios:: BaudRate ) > = None ;
604+ for ( text, baud_rate) in BAUD_RATES {
605+ if let Ok ( rate_val) = text. parse :: < u32 > ( ) {
606+ let diff = rate_val. abs_diff ( rounded) ;
607+ if closest. is_none ( ) || diff < closest. unwrap ( ) . 0 {
608+ closest = Some ( ( diff, * baud_rate) ) ;
609+ }
610+ }
611+ }
612+ if let Some ( ( _, baud_rate) ) = closest {
613+ return Some ( AllFlags :: Baud ( baud_rate) ) ;
614+ }
615+ }
578616 }
579-
617+
618+ // Fallback: try exact string match for non-numeric baud rate names
580619 #[ cfg( not( any(
581620 target_os = "freebsd" ,
582621 target_os = "dragonfly" ,
@@ -586,10 +625,11 @@ fn string_to_baud(arg: &str) -> Option<AllFlags<'_>> {
586625 target_os = "openbsd"
587626 ) ) ) ]
588627 for ( text, baud_rate) in BAUD_RATES {
589- if * text == arg {
628+ if * text == normalized {
590629 return Some ( AllFlags :: Baud ( * baud_rate) ) ;
591630 }
592631 }
632+
593633 None
594634}
595635
0 commit comments