Clap: Is it possible to support arg specifiers?

Created on 13 Jun 2017  ยท  5Comments  ยท  Source: clap-rs/clap

I'm trying to write a cli tool that is compatible with avconv.

The syntax peculiarity is to have specifiers :-separated

-c
-c:v
-c:v:1

would all map to codec, applying to all, only the video streams or only to the video stream with index 1.

I'm not sure if there is a way in clap to mimic this or how hard and/or acceptable to extend clap to support this kind of pattern.

RFC / question

Most helpful comment

Actually I'm mistaken...it does work! I'd completely forgotten about this syntax:

kevin@spawn: ~/Projects/codecs 
โžœ cat src/main.rs
extern crate clap;

use clap::{App, Arg};

fn main() {
    let m = App::new("codecs")
        .arg(Arg::from_usage("-c [opts] 'Some additional options for codec'")
            .min_values(0))
        .get_matches();

    println!("raw -c: {:?}", m.value_of("c"));
    println!("-c options: {}", m.value_of("c")
                                .unwrap_or("None")
                                .trim_left_matches(":")
                                .split(":")
                                .collect::<Vec<_>>()
                                .join(", "));
}

kevin@spawn: ~/Projects/codecs
โžœ ./target/debug/codecs -c
raw -c: None
-c options: None

kevin@spawn: ~/Projects/codecs 
โžœ ./target/debug/codecs -c:v
raw -c: Some(":v")
-c options: v

kevin@spawn: ~/Projects/codecs 
โžœ ./target/debug/codecs -c:v:1
raw -c: Some(":v:1")
-c options: v, 1

Note, that you'll have to handle the splitting of ":" and what those mean in user code...but Rust makes that super easy with matching and such.

All 5 comments

That's not directly possible in clap, due to being pretty niche. However, a small variation is possible in clap.

-c
-c=v
-c=v:1

This is possible by simply using Arg::value_delimiter(":").

By default this would also automatically work:

-c
-c v
-c v:1

If that's not desired, you can also set Arg::require_equals

I was investigating it to have a compatibility mode with existing scripts, so I'd really enjoy to have that as-is.

I know that's a fringe syntax and I'm enjoy clap so much I could probably just drop the idea of having a compatibility mode and just use an already supported syntax.

Actually I'm mistaken...it does work! I'd completely forgotten about this syntax:

kevin@spawn: ~/Projects/codecs 
โžœ cat src/main.rs
extern crate clap;

use clap::{App, Arg};

fn main() {
    let m = App::new("codecs")
        .arg(Arg::from_usage("-c [opts] 'Some additional options for codec'")
            .min_values(0))
        .get_matches();

    println!("raw -c: {:?}", m.value_of("c"));
    println!("-c options: {}", m.value_of("c")
                                .unwrap_or("None")
                                .trim_left_matches(":")
                                .split(":")
                                .collect::<Vec<_>>()
                                .join(", "));
}

kevin@spawn: ~/Projects/codecs
โžœ ./target/debug/codecs -c
raw -c: None
-c options: None

kevin@spawn: ~/Projects/codecs 
โžœ ./target/debug/codecs -c:v
raw -c: Some(":v")
-c options: v

kevin@spawn: ~/Projects/codecs 
โžœ ./target/debug/codecs -c:v:1
raw -c: Some(":v:1")
-c options: v, 1

Note, that you'll have to handle the splitting of ":" and what those mean in user code...but Rust makes that super easy with matching and such.

Amazing! Thank you a lot! I'll experiment with it during the weekend :)

I'm going to close this issue, feel free to re-open if a problem arises ๐Ÿ˜„

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pickfire picture pickfire  ยท  21Comments

joshtriplett picture joshtriplett  ยท  75Comments

kbknapp picture kbknapp  ยท  30Comments

jojva picture jojva  ยท  18Comments

casey picture casey  ยท  25Comments