-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
derive: Store indices, value source next to field values #3846
Comments
Was just mentioning this to someone else that we need an issue for this. The other piece of metadata we do not expose in the derive API is the I have some reticence for putting it in the same field due to the complications of parsing and processing more complex types like that. Another option is to take inspiration from
|
That would be great if correctness of id is checked at compile time. |
Something that could make it easier is #3171. My main hesitancy about it is I feel like derive-macros generating something besides a trait impl is a bit magical from the users perspective (hard to know what exists and how to interact with it). |
Going to copy over my discussion into this issue. 😄 @epage for deriving value source, I'd personally be happy with having some wrapper type that gets populated in the derive macro. Having some way to have this baked into the struct would enable me to handle #748 manually as I could still provide a default value for all of my cli arguments, but also manually replace them with a config file I've loaded separately just by knowing if the value is a default value. E.g. use clap::{Args, Value, parser::ValueSource};
#[derive(Args)]
struct MyArgs {
/// This has no value source encoded
#[clap(short, long)]
pub name: String,
/// This does have value source encoded
#[clap(short, long, value_source)]
pub age: Value<u8>,
}
// when accessing ...
let args: MyArgs = /* ... */;
assert_eq!(args.name, "some name");
assert_eq!(args.age, 37);
assert_eq!(args.age.source, ValueSource::CommandLine);
// if I had a config value I wanted to use only if the arg value came from the default
let age = args.age.replace_if_default(config.age);
assert_eq!(args.age, 28); use std::ops::{Deref, DerefMut};
use clap::parser::ValueSource;
// Value itself is a wrapper that looks like
#[derive(Copy, Clone)]
struct Value<T> {
inner: T,
pub source: ValueSource,
}
impl<T> Value<T> {
/// Returns the updated value if replaced, otherwise returns the original value
pub fn replace_if_default(self, inner: T) -> Self {
if self.source == ValueSource:: DefaultValue {
Value { inner, source: self.source }
} else {
self
}
}
}
impl<T> Deref for Value<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> DerefMut for Value<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<T> From<Value<T>> for T {
// To enable passing this value around as the actual type
fn from(value: Value<T>) -> Self {
value.inner
}
}
impl<T> PartialEq<T> for Value<T> where T: PartialEq {
// To enable equality checks
fn eq(&self, other: &T) -> bool {
self.inner == other
}
}
// do this for the other traits ... Originally posted by @chipsenkbeil in #3578 (reply in thread) |
@chipsenkbeil Thanks for copying that over! Having a It does have a scaling issue. Some users might want the source while others might want the index or both. Also the source common to all values while the index is per value. In exploring the various options, what are your thoughts on the parallel-field idea I had proposed earlier in the thread? |
@epage are you referring to the idea of |
Yes.
|
Unfortunately, this prevents clap from rendering the default revset in the help message, but I believe this is the only way to detect if the user has not not supplied an arg via the derive API. See clap-rs/clap#3846 fmi on getting the value_source of an arg via the derive API.
This doesn't do much for us now, but will soon be used to help us determine what type of smartlog we should be rendering. Unfortunately, this prevents clap from rendering the default revset in the help message, but I believe this is the only way (via the derive API) to detect if the user has or has not not supplied an arg for a particular value. See clap-rs/clap#3846 fmi on getting the value_source of an arg via the derive API.
This doesn't do much for us now, but will soon be used to help us determine what type of smartlog we should be rendering. Unfortunately, this prevents clap from rendering the default revset in the help message, but I believe this is the only way (via the derive API) to detect if the user has or has not not supplied an arg for a particular value. See clap-rs/clap#3846 fmi on getting the value_source of an arg via the derive API.
This doesn't do much for us now, but will soon be used to help us determine what type of smartlog we should be rendering. Unfortunately, this prevents clap from rendering the default revset in the help message, but I believe this is the only way (via the derive API) to detect if the user has or has not not supplied an arg for a particular value. See clap-rs/clap#3846 fmi on getting the value_source of an arg via the derive API.
This doesn't do much for us now, but will soon be used to help us determine what type of smartlog we should be rendering. Unfortunately, this prevents clap from rendering the default revset in the help message, but I believe this is the only way (via the derive API) to detect if the user has or has not not supplied an arg for a particular value. See clap-rs/clap#3846 fmi on getting the value_source of an arg via the derive API.
This doesn't do much for us now, but will soon be used to help us determine what type of smartlog we should be rendering. Unfortunately, this prevents clap from rendering the default revset in the help message, but I believe this is the only way (via the derive API) to detect if the user has or has not not supplied an arg for a particular value. See clap-rs/clap#3846 fmi on getting the value_source of an arg via the derive API.
This doesn't do much for us now, but will soon be used to help us determine what type of smartlog we should be rendering. Unfortunately, this prevents clap from rendering the default revset in the help message, but I believe this is the only way (via the derive API) to detect if the user has or has not not supplied an arg for a particular value. See clap-rs/clap#3846 fmi on getting the value_source of an arg via the derive API.
This doesn't do much for us now, but will soon be used to help us determine what type of smartlog we should be rendering. Unfortunately, this prevents clap from rendering the default revset in the help message, but I believe this is the only way (via the derive API) to detect if the user has or has not not supplied an arg for a particular value. See clap-rs/clap#3846 fmi on getting the value_source of an arg via the derive API.
This issue is unrelated. In the future, feel free to start a Discussion. In this case, value source is stable / should work. We'll need more details, like a reproduction case. Please create a Discussion with that to not detract from this Issue. |
Please complete the following tasks
Clap Version
3.1.8
Describe your use case
Be able to write something like this:
Currently to obtain indices, we need to work with
ArgMatches::indices_of
which is hard to work with when a command has subcommands which have other subcommands: it's too easy to miss some subcommand call, andindices
won't return what's expected (especially when subcommands share flags, but at different nesting level).Describe the solution you'd like
.
Alternatives, if applicable
No response
Additional Context
No response
The text was updated successfully, but these errors were encountered: