@@ -74,6 +74,8 @@ pub struct Arg<'a, 'b>
74
74
#[ doc( hidden) ]
75
75
pub default_val : Option < & ' a str > ,
76
76
#[ doc( hidden) ]
77
+ pub default_vals_ifs : Option < VecMap < ( & ' a str , Option < & ' b str > , & ' b str ) > > ,
78
+ #[ doc( hidden) ]
77
79
pub disp_ord : usize ,
78
80
#[ doc( hidden) ]
79
81
pub r_unless : Option < Vec < & ' a str > > ,
@@ -101,6 +103,7 @@ impl<'a, 'b> Default for Arg<'a, 'b> {
101
103
settings : ArgFlags :: new ( ) ,
102
104
val_delim : None ,
103
105
default_val : None ,
106
+ default_vals_ifs : None ,
104
107
disp_ord : 999 ,
105
108
r_unless : None ,
106
109
}
@@ -2359,6 +2362,14 @@ impl<'a, 'b> Arg<'a, 'b> {
2359
2362
/// not, consider [`ArgMatches::occurrences_of`] which will return `0` if the argument was *not*
2360
2363
/// used at runtmie.
2361
2364
///
2365
+ /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value_if`] but slightly
2366
+ /// different. `Arg::default_value` *only* takes affect when the user has not provided this arg
2367
+ /// at runtime. `Arg::default_value_if` however only takes affect when the user has not provided
2368
+ /// a value at runtime **and** these other conditions are met as well. If you have set
2369
+ /// `Arg::default_value` and `Arg::default_value_if`, and the user **did not** provide a this
2370
+ /// arg at runtime, nor did were the conditions met for `Arg::default_value_if`, the
2371
+ /// `Arg::default_value` will be applied.
2372
+ ///
2362
2373
/// **NOTE:** This implicitly sets [`Arg::takes_value(true)`].
2363
2374
///
2364
2375
/// # Examples
@@ -2400,12 +2411,207 @@ impl<'a, 'b> Arg<'a, 'b> {
2400
2411
/// [`ArgMatches::value_of`]: ./struct.ArgMatches.html#method.value_of
2401
2412
/// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
2402
2413
/// [`ArgMatches::is_present`]: ./struct.ArgMatches.html#method.is_present
2414
+ /// [`Arg::default_value_if`]: ./struct.Arg.html#method.default_value_if
2403
2415
pub fn default_value ( mut self , val : & ' a str ) -> Self {
2404
2416
self . setb ( ArgSettings :: TakesValue ) ;
2405
2417
self . default_val = Some ( val) ;
2406
2418
self
2407
2419
}
2408
2420
2421
+ /// Specifies the value of the argument if `arg` has been used at runtime. If `val` is set to
2422
+ /// `None`, `arg` only needs to be present. If `val` is set to `"some-val"` then `arg` must be
2423
+ /// present at runtime **and** have the value `val`.
2424
+ ///
2425
+ /// **NOTE:** This setting is perfectly compatible with [`Arg::default_value`] but slightly
2426
+ /// different. `Arg::default_value` *only* takes affect when the user has not provided this arg
2427
+ /// at runtime. This setting however only takes affect when the user has not provided a value at
2428
+ /// runtime **and** these other conditions are met as well. If you have set `Arg::default_value`
2429
+ /// and `Arg::default_value_if`, and the user **did not** provide a this arg at runtime, nor did
2430
+ /// were the conditions met for `Arg::default_value_if`, the `Arg::default_value` will be
2431
+ /// applied.
2432
+ ///
2433
+ /// **NOTE:** This implicitly sets [`Arg::takes_value(true)`].
2434
+ ///
2435
+ /// # Examples
2436
+ ///
2437
+ /// First we use the default value only if another arg is present at runtime.
2438
+ ///
2439
+ /// ```rust
2440
+ /// # use clap::{App, Arg};
2441
+ /// let m = App::new("dvif")
2442
+ /// .arg(Arg::with_name("flag")
2443
+ /// .long("flag"))
2444
+ /// .arg(Arg::with_name("other")
2445
+ /// .long("other")
2446
+ /// .default_value_if("flag", None, "default"))
2447
+ /// .get_matches_from(vec![
2448
+ /// "dvif", "--flag"
2449
+ /// ]);
2450
+ ///
2451
+ /// assert_eq!(m.value_of("other"), Some("default"));
2452
+ /// ```
2453
+ ///
2454
+ /// Next we run the same test, but without providing `--flag`.
2455
+ ///
2456
+ /// ```rust
2457
+ /// # use clap::{App, Arg};
2458
+ /// let m = App::new("dvif")
2459
+ /// .arg(Arg::with_name("flag")
2460
+ /// .long("flag"))
2461
+ /// .arg(Arg::with_name("other")
2462
+ /// .long("other")
2463
+ /// .default_value_if("flag", None, "default"))
2464
+ /// .get_matches_from(vec![
2465
+ /// "dvif"
2466
+ /// ]);
2467
+ ///
2468
+ /// assert_eq!(m.value_of("other"), None);
2469
+ /// ```
2470
+ ///
2471
+ /// Now lets only use the default value if `--opt` contains the value `special`.
2472
+ ///
2473
+ /// ```rust
2474
+ /// # use clap::{App, Arg};
2475
+ /// let m = App::new("dvif")
2476
+ /// .arg(Arg::with_name("opt")
2477
+ /// .takes_value(true)
2478
+ /// .long("opt"))
2479
+ /// .arg(Arg::with_name("other")
2480
+ /// .long("other")
2481
+ /// .default_value_if("opt", Some("special"), "default"))
2482
+ /// .get_matches_from(vec![
2483
+ /// "dvif", "--opt", "special"
2484
+ /// ]);
2485
+ ///
2486
+ /// assert_eq!(m.value_of("other"), Some("default"));
2487
+ /// ```
2488
+ ///
2489
+ /// We can run the same test and provide any value *other than* `special` and we won't get a
2490
+ /// default value.
2491
+ ///
2492
+ /// ```rust
2493
+ /// # use clap::{App, Arg};
2494
+ /// let m = App::new("dvif")
2495
+ /// .arg(Arg::with_name("opt")
2496
+ /// .takes_value(true)
2497
+ /// .long("opt"))
2498
+ /// .arg(Arg::with_name("other")
2499
+ /// .long("other")
2500
+ /// .default_value_if("opt", Some("special"), "default"))
2501
+ /// .get_matches_from(vec![
2502
+ /// "dvif", "--opt", "hahaha"
2503
+ /// ]);
2504
+ ///
2505
+ /// assert_eq!(m.value_of("other"), None);
2506
+ /// ```
2507
+ /// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
2508
+ /// [`Arg::default_value`]: ./struct.Arg.html#method.default_value
2509
+ pub fn default_value_if ( mut self , arg : & ' a str , val : Option < & ' b str > , default : & ' b str ) -> Self {
2510
+ self . setb ( ArgSettings :: TakesValue ) ;
2511
+ if let Some ( ref mut vm) = self . default_vals_ifs {
2512
+ let l = vm. len ( ) ;
2513
+ vm. insert ( l, ( arg, val, default) ) ;
2514
+ } else {
2515
+ let mut vm = VecMap :: new ( ) ;
2516
+ vm. insert ( 0 , ( arg, val, default) ) ;
2517
+ self . default_vals_ifs = Some ( vm) ;
2518
+ }
2519
+ self
2520
+ }
2521
+
2522
+ /// Specifies multiple values and conditions in the same manner as [`Arg::default_value_if`].
2523
+ /// The method takes a slice of tuples in the `(arg, Option<val>, default)` format.
2524
+ ///
2525
+ /// **NOTE**: The conditions are stored in order and evaluated in the same order. I.e. the first
2526
+ /// if multiple conditions are true, the first one found will be applied and the ultimate value.
2527
+ ///
2528
+ /// # Examples
2529
+ ///
2530
+ /// First we use the default value only if another arg is present at runtime.
2531
+ ///
2532
+ /// ```rust
2533
+ /// # use clap::{App, Arg};
2534
+ /// let m = App::new("dvif")
2535
+ /// .arg(Arg::with_name("flag")
2536
+ /// .long("flag"))
2537
+ /// .arg(Arg::with_name("opt")
2538
+ /// .long("opt")
2539
+ /// .takes_value(true))
2540
+ /// .arg(Arg::with_name("other")
2541
+ /// .long("other")
2542
+ /// .default_value_ifs(&[
2543
+ /// ("flag", None, "default"),
2544
+ /// ("opt", Some("channal"), "chan"),
2545
+ /// ])
2546
+ /// .get_matches_from(vec![
2547
+ /// "dvif", "--opt", "channal"
2548
+ /// ]);
2549
+ ///
2550
+ /// assert_eq!(m.value_of("other"), Some("chan"));
2551
+ /// ```
2552
+ ///
2553
+ /// Next we run the same test, but without providing `--flag`.
2554
+ ///
2555
+ /// ```rust
2556
+ /// # use clap::{App, Arg};
2557
+ /// let m = App::new("dvif")
2558
+ /// .arg(Arg::with_name("flag")
2559
+ /// .long("flag"))
2560
+ /// .arg(Arg::with_name("other")
2561
+ /// .long("other")
2562
+ /// .default_value_ifs(&[
2563
+ /// ("flag", None, "default"),
2564
+ /// ("opt", Some("channal"), "chan"),
2565
+ /// ])
2566
+ /// .get_matches_from(vec![
2567
+ /// "dvif"
2568
+ /// ]);
2569
+ ///
2570
+ /// assert_eq!(m.value_of("other"), None);
2571
+ /// ```
2572
+ ///
2573
+ /// We can also see that these values are applied in order, and if more than one condition is
2574
+ /// true, only the first evaluatd "wins"
2575
+ ///
2576
+ /// ```rust
2577
+ /// # use clap::{App, Arg};
2578
+ /// let m = App::new("dvif")
2579
+ /// .arg(Arg::with_name("flag")
2580
+ /// .long("flag"))
2581
+ /// .arg(Arg::with_name("other")
2582
+ /// .long("other")
2583
+ /// .default_value_ifs(&[
2584
+ /// ("flag", None, "default"),
2585
+ /// ("opt", Some("channal"), "chan"),
2586
+ /// ])
2587
+ /// .get_matches_from(vec![
2588
+ /// "dvif", "--opt", "channal", "--flag"
2589
+ /// ]);
2590
+ ///
2591
+ /// assert_eq!(m.value_of("other"), Some("default"));
2592
+ /// ```
2593
+ /// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
2594
+ /// [`Arg::default_value`]: ./struct.Arg.html#method.default_value
2595
+ pub fn default_value_ifs ( mut self , ifs : & [ ( & ' a str , Option < & ' b str > , & ' b str ) ] ) -> Self {
2596
+ self . setb ( ArgSettings :: TakesValue ) ;
2597
+ if let Some ( ref mut vm) = self . default_vals_ifs {
2598
+ let mut l = vm. len ( ) ;
2599
+ for & ( arg, val, default) in ifs {
2600
+ vm. insert ( l, ( arg, val, default) ) ;
2601
+ l += 1 ;
2602
+ }
2603
+ } else {
2604
+ let mut vm = VecMap :: new ( ) ;
2605
+ let mut l = 0 ;
2606
+ for & ( arg, val, default) in ifs {
2607
+ vm. insert ( l, ( arg, val, default) ) ;
2608
+ l += 1 ;
2609
+ }
2610
+ self . default_vals_ifs = Some ( vm) ;
2611
+ }
2612
+ self
2613
+ }
2614
+
2409
2615
/// When set to `true` the help string will be displayed on the line after the argument and
2410
2616
/// indented once. This can be helpful for arguments with very long or complex help messages.
2411
2617
/// This can also be helpful for arguments with very long flag names, or many/long value names.
@@ -2567,6 +2773,7 @@ impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for Arg<'a, 'b> {
2567
2773
settings : a. settings ,
2568
2774
val_delim : a. val_delim ,
2569
2775
default_val : a. default_val ,
2776
+ default_vals_ifs : a. default_vals_ifs . clone ( ) ,
2570
2777
disp_ord : a. disp_ord ,
2571
2778
r_unless : a. r_unless . clone ( ) ,
2572
2779
}
@@ -2595,6 +2802,7 @@ impl<'a, 'b> Clone for Arg<'a, 'b> {
2595
2802
settings : self . settings ,
2596
2803
val_delim : self . val_delim ,
2597
2804
default_val : self . default_val ,
2805
+ default_vals_ifs : self . default_vals_ifs . clone ( ) ,
2598
2806
disp_ord : self . disp_ord ,
2599
2807
r_unless : self . r_unless . clone ( ) ,
2600
2808
}
0 commit comments