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

How to express "either ... or ..." relationship #3121

Closed
epage opened this issue Dec 9, 2021 · 6 comments
Closed

How to express "either ... or ..." relationship #3121

epage opened this issue Dec 9, 2021 · 6 comments
Labels
A-derive Area: #[derive]` macro API

Comments

@epage
Copy link
Member

epage commented Dec 9, 2021

Issue by vbrandl
Monday Oct 08, 2018 at 14:58 GMT
Originally opened as TeXitoi/structopt#141


I want to express the following relationship using structopt: The positional parameter should either be two strings (username and password) or a PathBuf (from where the credentials will be read).

I tried the following:

#[derive(Debug, StructOpt)]
enum Opt {
    #[structopt(name = "login")]
    Login { param: LoginCredentials },
    #[structopt(name = "logout")]
    Logout,
}
#[derive(Debug, StructOpt)]
enum LoginCredentials {
    UserPass { loginid: String, password: String },
    File { path: PathBuf },
}

But this will create another subcommand for the login subcommand. What would be the right way to express this relationship? Is there even a way to do so?

@epage
Copy link
Member Author

epage commented Dec 9, 2021

Comment by TeXitoi
Thursday Oct 11, 2018 at 14:38 GMT


You might want to look at https://github.com/TeXitoi/structopt/blob/master/examples/group.rs and TeXitoi/structopt#126

@epage
Copy link
Member Author

epage commented Dec 9, 2021

Comment by vbrandl
Thursday Oct 11, 2018 at 14:59 GMT


I found that one already but I think it would be cool if we were able to describe groups using enums. That way it is impossible to represent an illegal state and you could simply match over the group variants.

Is it possible to implement this for structopt?

@epage
Copy link
Member Author

epage commented Dec 9, 2021

Comment by TeXitoi
Thursday Oct 11, 2018 at 15:14 GMT


That's a new feature, that's why I've tagged this issue enhancement. Then, we can design the details here, and anyone can implement that and do a PR to add it.

I will not implement this feature in short term, as I have others priorities, in this repo and in others. But I encourage anyone interested to contribute, and I'll try to answer any questions as fast as possible.

@epage
Copy link
Member Author

epage commented Dec 9, 2021

Comment by vbrandl
Thursday Oct 11, 2018 at 21:42 GMT


Just a few thoughts:

  • How this might be implemented
#[derive(Debug, StructOpt)]
#[structopt(type = "subcommand")] // this should be implicit
enum Opt {
    #[structopt(name = "login")]
    Login { param: LoginCredentials },
    #[structopt(name = "logout")]
    Logout,
}
#[derive(Debug, StructOpt)]
#[structopt(type = "group")]
enum LoginCredentials {
    UserPass { loginid: String, password: String },
    File { path: PathBuf },
}
  • Problem: Enums with variants that contain the same types and should be parsed as positional parameters cannot be distinguished and these cases should be compile errors
#[derive(Debug, StructOpt)]
#[structopt(type = "group")]
enum Group1 {
    Var1 { a: String, b: String },
    Var2 { c: String, d: String }, // this should fail
}

#[derive(Debug, StructOpt)]
#[structopt(type = "group")]
enum Group2 {
    Var1 { 
        #[structopt(short = "a")]
        a: String,
        b: String
    },
    Var2 { c: String, d: String },
} // this should work since the variants are distingushable

@epage
Copy link
Member Author

epage commented Dec 9, 2021

Comment by TeXitoi
Friday Oct 12, 2018 at 10:08 GMT


This is similar to #104

@epage
Copy link
Member Author

epage commented Dec 9, 2021

I believe this is covered by #2621

If there is something I'm missing though, let me know!

@epage epage closed this as completed Dec 9, 2021
@epage epage added the A-derive Area: #[derive]` macro API label Dec 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-derive Area: #[derive]` macro API
Projects
None yet
Development

No branches or pull requests

1 participant