@@ -21,22 +21,54 @@ pub struct DaemonOpts {
21
21
pub common : CommonOpts , // cov(skip)
22
22
23
23
/// Change detection polling interval in seconds
24
- #[ structopt( short = "p" , long = "poll" , default_value = "30" ) ]
24
+ #[ structopt(
25
+ short = "p" , long = "poll" , default_value = "30" ,
26
+ validator = validate_polling_interval) ]
25
27
pub polling_interval : u64 ,
26
28
27
29
/// Log to syslog (vice console)
28
30
#[ structopt( long = "syslog" ) ]
29
31
pub syslog : bool , // cov(skip)
30
32
31
33
/// Avahi D-Bus connection timeout
32
- #[ structopt( long = "timeout" , default_value = "60" ) ]
34
+ #[ structopt( long = "timeout" , default_value = "60" , validator = validate_timeout ) ]
33
35
pub timeout : u64 ,
34
36
35
37
/// Alias mDNS time-to-live (TTL) in seconds
36
- #[ structopt( long = "ttl" , default_value = "60" ) ]
38
+ #[ structopt( long = "ttl" , default_value = "60" , validator = validate_ttl ) ]
37
39
pub ttl : u64 ,
38
40
}
39
41
42
+ fn validate_polling_interval ( value : String ) -> Result < ( ) , String > {
43
+ match value. parse :: < u64 > ( ) {
44
+ Err ( error) => Err ( error. to_string ( ) ) ,
45
+ Ok ( timeout) if !( 10 ..=60 ) . contains ( & timeout) => {
46
+ Err ( "polling interval must be 10-60 seconds" . to_string ( ) )
47
+ } ,
48
+ _ => Ok ( ( ) ) ,
49
+ }
50
+ }
51
+
52
+ fn validate_timeout ( value : String ) -> Result < ( ) , String > {
53
+ match value. parse :: < u64 > ( ) {
54
+ Err ( error) => Err ( error. to_string ( ) ) ,
55
+ Ok ( timeout) if !( 10 ..=300 ) . contains ( & timeout) => {
56
+ Err ( "timeout must be 10-300 seconds" . to_string ( ) )
57
+ } ,
58
+ _ => Ok ( ( ) ) ,
59
+ }
60
+ }
61
+
62
+ fn validate_ttl ( value : String ) -> Result < ( ) , String > {
63
+ match value. parse :: < u64 > ( ) {
64
+ Err ( error) => Err ( error. to_string ( ) ) ,
65
+ Ok ( timeout) if timeout > ( i32:: MAX as u64 ) => {
66
+ Err ( "time-to-live (TTL) must be less than 2,147,483,648 (2^31) seconds" . to_string ( ) )
67
+ } ,
68
+ _ => Ok ( ( ) ) ,
69
+ }
70
+ }
71
+
40
72
#[ derive( Debug , StructOpt ) ]
41
73
pub struct CommonOpts {
42
74
/// Prints detailed messages
@@ -377,22 +409,117 @@ mod tests {
377
409
}
378
410
379
411
#[ test]
380
- fn daemon_timeout_option_works ( ) {
381
- let opts = DaemonOpts :: from_iter ( [ "" , "--timeout" , "100" ] ) ;
382
- assert_eq ! ( opts. timeout, 100 ) ;
412
+ fn polling_interval_validation_returns_ok_for_in_range_values ( ) {
413
+ assert ! ( validate_polling_interval( String :: from( "10" ) ) . is_ok( ) ) ;
414
+ assert ! ( validate_polling_interval( String :: from( "30" ) ) . is_ok( ) ) ;
415
+ assert ! ( validate_polling_interval( String :: from( "60" ) ) . is_ok( ) ) ;
383
416
}
384
417
385
418
#[ test]
386
- fn daemon_ttl_option_works ( ) {
387
- let opts = DaemonOpts :: from_iter ( [ "" , "--ttl" , "100" ] ) ;
388
- assert_eq ! ( opts. ttl, 100 ) ;
419
+ fn polling_interval_validation_returns_error_for_out_of_range_values ( ) {
420
+ assert ! ( validate_polling_interval( String :: from( "0" ) ) . is_err( ) ) ;
421
+ assert ! ( validate_polling_interval( String :: from( "9" ) ) . is_err( ) ) ;
422
+ assert ! ( validate_polling_interval( String :: from( "61" ) ) . is_err( ) ) ;
423
+ assert ! ( validate_polling_interval( String :: from( "120" ) ) . is_err( ) ) ;
424
+ }
425
+
426
+ #[ test]
427
+ fn polling_interval_validation_returns_error_for_invalid_values ( ) {
428
+ assert ! ( validate_polling_interval( String :: from( "not-a-number" ) ) . is_err( ) ) ;
429
+ }
430
+
431
+ #[ test]
432
+ fn polling_interval_validation_returns_correct_message_on_error ( ) {
433
+ assert_eq ! (
434
+ validate_polling_interval( String :: from( "0" ) ) . unwrap_err( ) ,
435
+ "polling interval must be 10-60 seconds"
436
+ ) ;
437
+ assert_eq ! (
438
+ validate_polling_interval( String :: from( "not-a-number" ) ) . unwrap_err( ) ,
439
+ "invalid digit found in string"
440
+ ) ;
441
+ }
442
+
443
+ #[ test]
444
+ fn timeout_validation_returns_ok_for_in_range_values ( ) {
445
+ assert ! ( validate_timeout( String :: from( "10" ) ) . is_ok( ) ) ;
446
+ assert ! ( validate_timeout( String :: from( "60" ) ) . is_ok( ) ) ;
447
+ assert ! ( validate_timeout( String :: from( "300" ) ) . is_ok( ) ) ;
448
+ }
449
+
450
+ #[ test]
451
+ fn timeout_validation_returns_error_for_out_of_range_values ( ) {
452
+ assert ! ( validate_timeout( String :: from( "0" ) ) . is_err( ) ) ;
453
+ assert ! ( validate_timeout( String :: from( "9" ) ) . is_err( ) ) ;
454
+ assert ! ( validate_timeout( String :: from( "301" ) ) . is_err( ) ) ;
455
+ assert ! ( validate_timeout( String :: from( "600" ) ) . is_err( ) ) ;
456
+ }
457
+
458
+ #[ test]
459
+ fn timeout_validation_returns_error_for_invalid_values ( ) {
460
+ assert ! ( validate_timeout( String :: from( "not-a-number" ) ) . is_err( ) ) ;
461
+ }
462
+
463
+ #[ test]
464
+ fn timeout_validation_returns_correct_message_on_error ( ) {
465
+ assert_eq ! (
466
+ validate_timeout( String :: from( "0" ) ) . unwrap_err( ) ,
467
+ "timeout must be 10-300 seconds"
468
+ ) ;
469
+ assert_eq ! (
470
+ validate_timeout( String :: from( "not-a-number" ) ) . unwrap_err( ) ,
471
+ "invalid digit found in string"
472
+ ) ;
473
+ }
474
+
475
+ #[ test]
476
+ fn ttl_validation_returns_ok_for_in_range_values ( ) {
477
+ assert ! ( validate_ttl( String :: from( "0" ) ) . is_ok( ) ) ;
478
+ assert ! ( validate_ttl( String :: from( "30" ) ) . is_ok( ) ) ;
479
+ assert ! ( validate_ttl( String :: from( "86400" ) ) . is_ok( ) ) ;
480
+ assert ! ( validate_ttl( i32 :: MAX . to_string( ) ) . is_ok( ) ) ;
481
+ }
482
+
483
+ #[ test]
484
+ fn ttl_validation_returns_error_for_out_of_range_values ( ) {
485
+ assert ! ( validate_ttl( ( ( i32 :: MAX as u64 ) + 1 ) . to_string( ) ) . is_err( ) ) ;
486
+ assert ! ( validate_ttl( u64 :: MAX . to_string( ) ) . is_err( ) ) ;
487
+ }
488
+
489
+ #[ test]
490
+ fn ttl_validation_returns_error_for_invalid_values ( ) {
491
+ assert ! ( validate_ttl( String :: from( "not-a-number" ) ) . is_err( ) ) ;
492
+ }
493
+
494
+ #[ test]
495
+ fn ttl_validation_returns_correct_message_on_error ( ) {
496
+ assert_eq ! (
497
+ validate_ttl( ( ( i32 :: MAX as u64 ) + 1 ) . to_string( ) ) . unwrap_err( ) ,
498
+ "time-to-live (TTL) must be less than 2,147,483,648 (2^31) seconds"
499
+ ) ;
500
+ assert_eq ! (
501
+ validate_ttl( String :: from( "not-a-number" ) ) . unwrap_err( ) ,
502
+ "invalid digit found in string"
503
+ ) ;
389
504
}
390
505
391
506
#[ test]
392
507
fn daemon_syslog_option_works ( ) {
393
508
let opts = DaemonOpts :: from_iter ( [ "" , "--syslog" ] ) ;
394
509
assert ! ( opts. syslog) ;
395
510
}
511
+
512
+ #[ test]
513
+ fn daemon_timeout_option_works ( ) {
514
+ let opts = DaemonOpts :: from_iter ( [ "" , "--timeout" , "100" ] ) ;
515
+ assert_eq ! ( opts. timeout, 100 ) ;
516
+ }
517
+
518
+ #[ test]
519
+ fn daemon_ttl_option_works ( ) {
520
+ let opts = DaemonOpts :: from_iter ( [ "" , "--ttl" , "100" ] ) ;
521
+ assert_eq ! ( opts. ttl, 100 ) ;
522
+ }
396
523
}
397
524
398
525
// end
0 commit comments