I'm a bit confused on the distinction between the default_value_t
and default_missing_value
attributes in the process of building my first command-line program using the clap crate in Rust. The following code snippet was taken from clap's documentation on Git's cookbook for the derive API as an example:
#[derive(Debug, Subcommand)]
enum Commands {
/// Compare two commits
Diff {
#[arg(value_name = "COMMIT")]
base: Option<OsString>,
#[arg(value_name = "COMMIT")]
head: Option<OsString>,
#[arg(last = true)]
path: Option<OsString>,
#[arg(
long,
require_equals = true,
value_name = "WHEN",
num_args = 0..=1,
default_value_t = ColorWhen::Auto, // <- This
default_missing_value = "always", // <- and this part.
value_enum
)]
color: ColorWhen,
},
#[derive(ValueEnum, Copy, Clone, Debug, PartialEq, Eq)]
enum ColorWhen {
Always,
Auto,
Never,
}
I have pointed it out with comments in the code example.
As I understand it, default_missing_value
appears to be useful when, let's say an argument --foo
can take multiple values. And in such a case when a value isn't provided, it defaults to whatever default_missing_value
is set to. However to me, default_value_t
seems to serve the same or a similar purpose?
Could someone help clarify the difference between default_value_t
and default_missing_value
? Examples are much appreciated.
All the various directives are documented more extensively as methods of clap::Arg
.
As I understand it, default_missing_value appears to be useful when, let's say an argument --foo can take multiple values.
It does not have anything to do with mutliple values.
However to me, default_value_t seems to serve the same or a similar purpose?
They have similar but different purposes, per the documentation linked above:
pub fn default_value(self, val: impl IntoResettable<OsStr>) -> Arg
Value for the argument when not present.
pub fn default_missing_value(self, val: impl IntoResettable<OsStr>) -> Arg
Value for the argument when the flag is present but no value is specified.
So default_value
[0] is invoked when the argument is missing from the command line e.g.
git diff
while default_missing_value
is invoked when the argument is present but has no value e.g.
git diff --color
In the case of git the former means "defer to the configuration file (/ whether stdout is a term)" while the latter means "force colorized output". That is why they are both set, with different behaviours.
[0] the declarative default_value_t
and default_value
map to essentially the same thing, it's just that the former is post-parse (e.g. it might be a number) while the latter is pre-parse (it's always a string literal).