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
.It does not have anything to do with mutliple values.
They have similar but different purposes, per the documentation linked above:
So
default_value
[0] is invoked when the argument is missing from the command line e.g.while
default_missing_value
is invoked when the argument is present but has no value e.g.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
anddefault_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).