These are chat archives for kbknapp/clap-rs

May 2015
Andres Vahter
May 20 2015 12:44

Subcommand -h should override other required parameters.
For example here 2 required parameters are defined (samplerate, bandwidth) and 2 subcommands (fm, am).
If I do:

app fm -h

It says that samplerate and bandwidth is not given, however I just wanted to peek which parameters "fm" subcommand wants.
So currently I have to do this to see subcommand help:

app --samplerate 0 --bandwidth 0 fm -h

Workaround is to define samplerate and bandwidth under each subcommand, however it means I have to copy them manually.
So I guess subcommand -h should override other requirements.

use clap::{App, Arg, SubCommand};
use self::DataType::{F32, I16};
use self::Modulation::{FM, AM};

use std::fmt;
use std::process::exit;

#[derive(Clone, Copy)]
pub enum DataType {

impl fmt::Display for DataType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            DataType::F32 => {write!(f, "f32")},
            DataType::I16 => {write!(f, "i16")},

pub enum Modulation {

pub struct FmModulationArgs {
    pub deviation: Option<u32>,

pub struct CommandArgs {
    pub samplerate: Option<u32>,
    pub resamplerate: Option<u32>,
    pub inputtype: Option<DataType>,
    pub bandwidth: Option<u32>,
    pub modulation: Option<Modulation>,

    pub fmargs: FmModulationArgs,

pub fn args() -> CommandArgs {
    let datatypes = ["i16", "f32"];

    let matches = App::new("demod")
                .about("Reads IQ data from stdin, filters and demodulates according to parameters and writes demodulated data back to stdout")

                    .help("IQ data input samplerate")
                    .help("bandpass filter bandwidth")

                    .about("FM demodulation")

                        .help("FM deviation")

                    .about("AM demodulation")

                        .help("AM arg")


    let mut args = CommandArgs {
                    samplerate : None,
                    resamplerate : None,
                    inputtype : None,
                    bandwidth : None,
                    modulation : None,

                    fmargs : FmModulationArgs {
                        deviation: None,

Kevin K.
May 20 2015 12:49
Yeah, I actually op
Andres Vahter
May 20 2015 12:52

Here I used this copy paste approach:
However it gets quite messy if there are more than 2 subcommands that share the same required args.

I guess app subcommand -h should actually show also required arguments in usage string, because they are indeed required to run this command.

Kevin K.
May 20 2015 12:53
Opened an issue on this a few days ago, but its a difficult problem to solve without pre scanning the arguments for a help switch or some sort of lookahead. What makes this hard is each subcommand can override the help switches.
Andres Vahter
May 20 2015 12:55
I made a mistake in my last comment, actually it shows required args, they were commented out in my test. So just overriding would be wonderful.
Kevin K.
May 20 2015 12:55
This is definitely on my radar, but I'll have to play with some different implementations to see if there's an efficient way to do it
Andres Vahter
May 20 2015 12:57
I think I have tried 4 different arg parsers. Keep up the good work, clap is the best so far.
Kevin K.
May 20 2015 13:00
There is a workaround that works, but it's not the best solution. You can have your app use .subcommands_negate_reqs(true) and if your subcommands actually do require app's required arguments, you can simply check for their existance at runtime and print an error/std::process::exit(1) if they aren't there (i.e. the user tried app subcommand <required> instead of app subcommand -h
Thanks! I'll definitely let you know once this particular issue gets solved, because it would also make a utility I'm writing better as well ;)
See issue #124 to follow the progress
Kevin K.
May 20 2015 15:53
Checkout v0.9.2 on, this issue should be fixed now ;)