Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

structopt as main args through rust-cli/paw #187

Closed
yoshuawuyts opened this issue May 26, 2019 · 7 comments
Closed

structopt as main args through rust-cli/paw #187

yoshuawuyts opened this issue May 26, 2019 · 7 comments
Labels
enhancement We would love to have this feature! Feel free to supply a PR

Comments

@yoshuawuyts
Copy link

A few weeks ago the CLI WG released paw, a crate to try and make CLI parsing more of a first-class citizen in Rust (post). This allows arguments to be passed into fn main as long as a trait is implemented. Obviously we also added structopt support.

So far it's been working quite well, but we think we could make this even better if we could add the trait to structopt directly:

Proposed

#[derive(structopt::StructOpt)]
struct Args {}

#[paw::main]
fn main(args: Args) {
    println!("{}", args);
}

Current

#[derive(paw_structopt::StructOpt, structopt::StructOpt)]
struct Args {}

#[paw::main]
fn main(args: Args) {
    println!("{}", args);
}

Implementation

The patch to structopt would be about 6 lines inside the structopt macro:

impl paw::ParseArgs for #name {
    type Error = std::io::Error;
    fn parse_args() -> Result<Self, Self::Error> {
        Ok(<#name as structopt::StructOpt>::from_args())
    }
}

Would you be open to a patch that allows structopt to be used directly from main?


Full TCP Example

#[derive(structopt::StructOpt)]
struct Args {
    #[structopt(flatten)]
    port: clap_port_flag::Address,
    #[structopt(flatten)]
    port: clap_port_flag::Port,
}

#[paw::main]
fn main(args: Args) -> Result<(), std::io::Error> {
    let listener = TcpListener::bind((&*args.address, args.port))?;
    println!("listening on {}", listener.local_addr()?);
    for stream in listener.incoming() {
        stream?.write(b"hello world!")?;
    }
    Ok(())
}
@yoshuawuyts yoshuawuyts changed the title Support Paw structopt as main args through rust-cli/paw May 26, 2019
@TeXitoi
Copy link
Owner

TeXitoi commented May 26, 2019

Can't you just impl<T> ParseArg for T where T: StructOpt

@yoshuawuyts
Copy link
Author

@TeXitoi unfortunately we can't because we're not allowed to implement traits for foreign types (believe it's because of orphan rules):

2019-05-27-114218_1920x1080

Maybe I'm missing something tho?

@TeXitoi
Copy link
Owner

TeXitoi commented May 27, 2019

As paw-raw is very small, I'm OK adding the generic impl in the structopt crate (and not in the generated code as proposed above).

@TeXitoi TeXitoi added the enhancement We would love to have this feature! Feel free to supply a PR label May 27, 2019
@TeXitoi
Copy link
Owner

TeXitoi commented May 27, 2019

@yoshuawuyts I let you open the PR? I don't know when I'll find the time to do that, but if you do it, it'll be faster.

@yoshuawuyts
Copy link
Author

yoshuawuyts commented May 29, 2019

@TeXitoi yeah for sure; I learned today that @gameldar has been working on a PR that sounds quite promising!

@gameldar
Copy link
Contributor

gameldar commented Jun 1, 2019

I've just created PR #192 to address this. After trying a few different methods I had to go back to doing this in the structopt macro as the error @yoshuawuyts was seeing shows up because of the way ParseArgs is invoked. The only way I could get this working was to do it in paw which introduced a dependency on structopt for paw which given the intention to move paw to std at some point (so cannot have dependencies) is not an option.

@TeXitoi
Copy link
Owner

TeXitoi commented Jun 1, 2019

resolved by #192

@TeXitoi TeXitoi closed this as completed Jun 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement We would love to have this feature! Feel free to supply a PR
Projects
None yet
Development

No branches or pull requests

3 participants