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

Add logic to ArgPredicate #4731

Open
2 tasks done
jaskij opened this issue Feb 27, 2023 · 2 comments
Open
2 tasks done

Add logic to ArgPredicate #4731

jaskij opened this issue Feb 27, 2023 · 2 comments
Labels
C-enhancement Category: Raise on the bar on expectations

Comments

@jaskij
Copy link

jaskij commented Feb 27, 2023

Please complete the following tasks

Clap Version

4.1.6

Describe your use case

I want to set an arguments default value, using default_value_ifs() depending on multiple other arguments.

For example, in the code below, I would like to change the value for destination depending on the value of data_type (since in actual usage the UDP port depends on the type of data we're sending).

#[derive(Debug, clap::Parser)]
#[command(
    long_about = None,
    long_version(crate::build_info::BUILD_INFO.long_version_string(),
))]
pub(crate) struct Cli {
    #[arg(value_enum)]
    // Which data type to send
    pub(crate) data_type: DataType,

    #[arg(value_enum)]
    // How to send
    pub(crate) sender: Sender,

    #[arg(
        short,
        long,
        default_value_ifs([
            ("sender", clap::builder::ArgPredicate::Equals("nats".into()), "localhost:4222"),
            ("sender", clap::builder::ArgPredicate::Equals("udp".into()), "localhost:8585")
        ]),
    )]
    /// Where to send
    pub destination: String,
}

Describe the solution you'd like

The idea is to expand ArgPredicate to look something like this:

pub enum ArgPredicate {
    IsPresent,
    Equals(OsStr),
    And(ArgPredicate, ArgPredicate),
    Or(ArgPredicate, ArgPredicate),
}

Alternatives, if applicable

No idea

Additional Context

No response

@jaskij jaskij added the C-enhancement Category: Raise on the bar on expectations label Feb 27, 2023
@epage
Copy link
Member

epage commented Feb 27, 2023

We've talked of generalizing a lot of this logic in #3476.

For this specific proposal, I'm not seeing how it would work as it sounds like you want a default for destination to read both sender and data_type but ArgPredicate doesn't support that, so adding And and Or wouldn't do much.

@jaskij
Copy link
Author

jaskij commented Feb 27, 2023

Argh, my bad. Yes, it does not read multiple arguments. So the change would require moving the argument name into the predicate, like so:

pub enum ArgPredicate {
    IsPresent,
    Equals(OsStr, OsStr),
    And(ArgPredicate, ArgPredicate),
    Or(ArgPredicate, ArgPredicate),
}

But, I just realized that this would lead to a full-blown logic system and end up with an inner platform effect. So might as wall ditch the predicate, accept something like Fn(&HashMap<OsStr, OsStr>) -> OsStr and let clap's user worry about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: Raise on the bar on expectations
Projects
None yet
Development

No branches or pull requests

2 participants