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

Support default_missing_value_t, default_value_if_t, etc #2813

Open
2 tasks done
epage opened this issue Oct 5, 2021 · 4 comments
Open
2 tasks done

Support default_missing_value_t, default_value_if_t, etc #2813

epage opened this issue Oct 5, 2021 · 4 comments
Labels
A-derive Area: #[derive]` macro API C-enhancement Category: Raise on the bar on expectations S-waiting-on-decision Status: Waiting on a go/no-go before implementing

Comments

@epage
Copy link
Member

epage commented Oct 5, 2021

Please complete the following tasks

  • I have searched the discussions
  • I have searched the existing issues

Clap Version

v3.0.0-beta.4

Describe your use case

clap_derive has a default_value_t attribute that takes a rust data type, instead of a string, and sets it as default_value on the Arg.

However, there are related functions that are missing similar _t magic methods

Describe the solution you'd like

Add magic methods for other raw methods that accept a value corresponding to the field the attribute is applied to

Alternatives, if applicable

No response

Additional Context

No response

@epage epage added C-enhancement Category: Raise on the bar on expectations T: new feature A-derive Area: #[derive]` macro API labels Oct 5, 2021
@marjakm
Copy link
Contributor

marjakm commented Nov 4, 2021

As I see it, those methods are all special cases of a pattern that uses a type to generate some code, but why allow only a few special cases not all such patterns?

default_value_t basically generates a call to

pub struct Arg {
    pub fn default_value(self, val: &'help str) -> Self;
}

as something like this:

arg = Arg::default_value(arg, generate_default_from_type!{T});

generate_default_from_type is a special macro in generator, adding default_missing_value_t support would mean creating a similar macro that also takes the type T. Why only allow this pattern for macros defined in the code generator, why not allow the user of the library to provide the macro (or maybe function) and generate code that provides the type to the user-defined macro (or function).

It could be implemented by allowing the user to annotate like such:

    struct Opt {
        #[clap(modify_t(my_mod))]
        arg: i32,
    }
    
    fn my_mod<T: Default + serde::Serialize>(a: Arg) -> Arg {
        let val: &'static str = todo!("serialize default T with serde_json, and leak boxed string");
        a.default_value(val)
         .default_value_if(todo!(), todo!(), todo!())
    }

Derive crate could generate something like this:

arg = my_mod::<T>(arg);

It would still be useful to have attributes such as default_value_t and default_missing_value_t, but they could be implemented via having the macros defined as functions somewhere and converting default_missing_value_t to modify_t(generate_default_from_type).

@marjakm
Copy link
Contributor

marjakm commented Nov 4, 2021

I actually would like to generate Arg::about calls in just this way - the arg parses Option<ComplexStruct> via json, the default value should be the empty string, but I'd like to generate an example json in the about.

If you like the above-described solution, I could actually try implementing it and making a pull request

@epage
Copy link
Member Author

epage commented Nov 4, 2021

Let's split that out into its own issue to talk about. This is specifically about providing natively typed magic methods that map to regular methods.

@epage
Copy link
Member Author

epage commented Nov 4, 2021

Also of note: we might want to see how #2683 impacts this issue.

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 C-enhancement Category: Raise on the bar on expectations S-waiting-on-decision Status: Waiting on a go/no-go before implementing
Projects
None yet
Development

No branches or pull requests

2 participants