@@ -408,14 +408,40 @@ mod clap {
408
408
. parse_ref ( cmd, arg, value)
409
409
}
410
410
}
411
+
412
+ #[ derive( Clone ) ]
413
+ pub struct AsRange ;
414
+
415
+ impl TypedValueParser for AsRange {
416
+ type Value = std:: ops:: Range < u32 > ;
417
+
418
+ fn parse_ref ( & self , cmd : & Command , arg : Option < & Arg > , value : & OsStr ) -> Result < Self :: Value , Error > {
419
+ StringValueParser :: new ( )
420
+ . try_map ( |arg| -> Result < _ , Box < dyn std:: error:: Error + Send + Sync > > {
421
+ let parts = arg. split_once ( ',' ) ;
422
+ if let Some ( ( start, end) ) = parts {
423
+ let start = u32:: from_str ( start) ?;
424
+ let end = u32:: from_str ( end) ?;
425
+
426
+ if start <= end {
427
+ return Ok ( start..end) ;
428
+ }
429
+ }
430
+
431
+ Err ( Box :: new ( Error :: new ( ErrorKind :: ValueValidation ) ) )
432
+ } )
433
+ . parse_ref ( cmd, arg, value)
434
+ }
435
+ }
411
436
}
412
437
pub use self :: clap:: {
413
- AsBString , AsHashKind , AsOutputFormat , AsPartialRefName , AsPathSpec , AsTime , CheckPathSpec , ParseRenameFraction ,
438
+ AsBString , AsHashKind , AsOutputFormat , AsPartialRefName , AsPathSpec , AsRange , AsTime , CheckPathSpec ,
439
+ ParseRenameFraction ,
414
440
} ;
415
441
416
442
#[ cfg( test) ]
417
443
mod value_parser_tests {
418
- use super :: ParseRenameFraction ;
444
+ use super :: { AsRange , ParseRenameFraction } ;
419
445
use clap:: Parser ;
420
446
421
447
#[ test]
@@ -441,4 +467,16 @@ mod value_parser_tests {
441
467
let c = Cmd :: parse_from ( [ "cmd" , "-a=75" ] ) ;
442
468
assert_eq ! ( c. arg, Some ( Some ( 0.75 ) ) ) ;
443
469
}
470
+
471
+ #[ test]
472
+ fn range ( ) {
473
+ #[ derive( Debug , clap:: Parser ) ]
474
+ pub struct Cmd {
475
+ #[ clap( long, short='l' , value_parser = AsRange ) ]
476
+ pub arg : Option < std:: ops:: Range < u32 > > ,
477
+ }
478
+
479
+ let c = Cmd :: parse_from ( [ "cmd" , "-l=1,10" ] ) ;
480
+ assert_eq ! ( c. arg, Some ( 1 ..10 ) ) ;
481
+ }
444
482
}
0 commit comments