knurling-rs / flip-link

Adds zero-cost stack overflow protection to your embedded programs
Apache License 2.0
279 stars 8 forks source link

Add structopt #29

Closed Urhengulas closed 3 years ago

Urhengulas commented 3 years ago

This PR introduces sctructopt for handling cli-params.

Urhengulas commented 3 years ago

This PR is blocked by the fact that we need to accept way more args than we are actually using here. In best case we can just ignore them, but I couldn't figure out how to do that.

I've tried clap::AppSettings::TrailingVarArg, but this didn't work so far, since we also need to accept arguments in the middle, and not only at the end.

Urhengulas commented 3 years ago

https://github.com/clap-rs/clap/issues/1404 would be helpful for solving our blocker.

Urhengulas commented 3 years ago

One approach I though might be useful is to "pre-filter" the arguments (std::env::args()) and then parse them with StructOpt::from_iter(...). A sketch is appended.

More generally some lightweight parser to extract specific args from the cli-args and ignore the rest, would be very useful for our kind of cli (being a cli-wrapper around another cli)!

pre-filter example

use std::{env, path::PathBuf};

use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
    #[structopt(short = "-L", long, parse(from_os_str))]
    library_path: Vec<PathBuf>,

    #[structopt(short, long, parse(from_os_str))]
    output: PathBuf,

    #[structopt(short = "T", long)]
    script: Vec<String>,
}

fn main() {
    let app = Opt::clap().p.opts;

    // get long arguments, e.g. `--output`, `--script`
    let mut long = app.iter().filter_map(|opt| opt.s.long).collect::<Vec<_>>();
    long.extend(["help", "version"].iter());

    // get short arguments, e.g. `-o`, `-T`
    let mut short = app.iter().filter_map(|x| x.s.short).collect::<Vec<_>>();
    short.extend(['H', 'V'].iter());

    dbg!(long, short);

    // filter one element args
    let short_args = env::args()
        // check if `x` starts with '-' and 2nd char is in `short`
        .filter(|x| unimplemented!())
        .collect::<Vec<_>>();
    // filter two element args
    let long_args: Vec<&[String]> = unimplemented!();

    // merge args
    let args: Vec<String> = unimplemented!(); // shorts_args + long_args

    let opt: Opt = Opt::from_iter(args);
    dbg!(opt);
}