Skip to content

Commit 6720240

Browse files
committed
feat(parser): Report source to value parsers
1 parent b55ebc9 commit 6720240

File tree

2 files changed

+84
-8
lines changed

2 files changed

+84
-8
lines changed

clap_builder/src/builder/value_parser.rs

+71-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::ops::RangeBounds;
33

44
use crate::builder::Str;
55
use crate::builder::StyledStr;
6+
use crate::parser::ValueSource;
67
use crate::util::AnyValue;
78
use crate::util::AnyValueId;
89

@@ -236,8 +237,9 @@ impl ValueParser {
236237
cmd: &crate::Command,
237238
arg: Option<&crate::Arg>,
238239
value: &std::ffi::OsStr,
240+
source: ValueSource,
239241
) -> Result<AnyValue, crate::Error> {
240-
self.any_value_parser().parse_ref(cmd, arg, value)
242+
self.any_value_parser().parse_ref_(cmd, arg, value, source)
241243
}
242244

243245
/// Describes the content of `AnyValue`
@@ -594,13 +596,33 @@ trait AnyValueParser: Send + Sync + 'static {
594596
value: &std::ffi::OsStr,
595597
) -> Result<AnyValue, crate::Error>;
596598

599+
fn parse_ref_(
600+
&self,
601+
cmd: &crate::Command,
602+
arg: Option<&crate::Arg>,
603+
value: &std::ffi::OsStr,
604+
_source: ValueSource,
605+
) -> Result<AnyValue, crate::Error> {
606+
self.parse_ref(cmd, arg, value)
607+
}
608+
597609
fn parse(
598610
&self,
599611
cmd: &crate::Command,
600612
arg: Option<&crate::Arg>,
601613
value: std::ffi::OsString,
602614
) -> Result<AnyValue, crate::Error>;
603615

616+
fn parse_(
617+
&self,
618+
cmd: &crate::Command,
619+
arg: Option<&crate::Arg>,
620+
value: std::ffi::OsString,
621+
_source: ValueSource,
622+
) -> Result<AnyValue, crate::Error> {
623+
self.parse(cmd, arg, value)
624+
}
625+
604626
/// Describes the content of `AnyValue`
605627
fn type_id(&self) -> AnyValueId;
606628

@@ -626,6 +648,17 @@ where
626648
Ok(AnyValue::new(value))
627649
}
628650

651+
fn parse_ref_(
652+
&self,
653+
cmd: &crate::Command,
654+
arg: Option<&crate::Arg>,
655+
value: &std::ffi::OsStr,
656+
source: ValueSource,
657+
) -> Result<AnyValue, crate::Error> {
658+
let value = ok!(TypedValueParser::parse_ref_(self, cmd, arg, value, source));
659+
Ok(AnyValue::new(value))
660+
}
661+
629662
fn parse(
630663
&self,
631664
cmd: &crate::Command,
@@ -636,6 +669,17 @@ where
636669
Ok(AnyValue::new(value))
637670
}
638671

672+
fn parse_(
673+
&self,
674+
cmd: &crate::Command,
675+
arg: Option<&crate::Arg>,
676+
value: std::ffi::OsString,
677+
source: ValueSource,
678+
) -> Result<AnyValue, crate::Error> {
679+
let value = ok!(TypedValueParser::parse_(self, cmd, arg, value, source));
680+
Ok(AnyValue::new(value))
681+
}
682+
639683
fn type_id(&self) -> AnyValueId {
640684
AnyValueId::of::<T>()
641685
}
@@ -716,6 +760,19 @@ pub trait TypedValueParser: Clone + Send + Sync + 'static {
716760
value: &std::ffi::OsStr,
717761
) -> Result<Self::Value, crate::Error>;
718762

763+
/// Parse the argument value
764+
///
765+
/// When `arg` is `None`, an external subcommand value is being parsed.
766+
fn parse_ref_(
767+
&self,
768+
cmd: &crate::Command,
769+
arg: Option<&crate::Arg>,
770+
value: &std::ffi::OsStr,
771+
_source: ValueSource,
772+
) -> Result<Self::Value, crate::Error> {
773+
self.parse_ref(cmd, arg, value)
774+
}
775+
719776
/// Parse the argument value
720777
///
721778
/// When `arg` is `None`, an external subcommand value is being parsed.
@@ -728,6 +785,19 @@ pub trait TypedValueParser: Clone + Send + Sync + 'static {
728785
self.parse_ref(cmd, arg, &value)
729786
}
730787

788+
/// Parse the argument value
789+
///
790+
/// When `arg` is `None`, an external subcommand value is being parsed.
791+
fn parse_(
792+
&self,
793+
cmd: &crate::Command,
794+
arg: Option<&crate::Arg>,
795+
value: std::ffi::OsString,
796+
_source: ValueSource,
797+
) -> Result<Self::Value, crate::Error> {
798+
self.parse(cmd, arg, value)
799+
}
800+
731801
/// Reflect on enumerated value properties
732802
///
733803
/// Error checking should not be done with this; it is mostly targeted at user-facing

clap_builder/src/parser/parser.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,12 @@ impl<'cmd> Parser<'cmd> {
421421
sc_m.start_occurrence_of_external(self.cmd);
422422

423423
for raw_val in raw_args.remaining(&mut args_cursor) {
424-
let val = ok!(external_parser.parse_ref(self.cmd, None, raw_val));
424+
let val = ok!(external_parser.parse_ref(
425+
self.cmd,
426+
None,
427+
raw_val,
428+
ValueSource::CommandLine
429+
));
425430
let external_id = Id::from_static_ref(Id::EXTERNAL);
426431
sc_m.add_val_to(&external_id, val, raw_val.to_os_string());
427432
}
@@ -1032,6 +1037,7 @@ impl<'cmd> Parser<'cmd> {
10321037
&self,
10331038
arg: &Arg,
10341039
raw_vals: Vec<OsString>,
1040+
source: ValueSource,
10351041
matcher: &mut ArgMatcher,
10361042
) -> ClapResult<()> {
10371043
debug!("Parser::push_arg_values: {raw_vals:?}");
@@ -1044,7 +1050,7 @@ impl<'cmd> Parser<'cmd> {
10441050
self.cur_idx.get()
10451051
);
10461052
let value_parser = arg.get_value_parser();
1047-
let val = ok!(value_parser.parse_ref(self.cmd, Some(arg), &raw_val));
1053+
let val = ok!(value_parser.parse_ref(self.cmd, Some(arg), &raw_val, source));
10481054

10491055
matcher.add_val_to(arg.get_id(), val, raw_val);
10501056
matcher.add_index_to(arg.get_id(), self.cur_idx.get());
@@ -1153,7 +1159,7 @@ impl<'cmd> Parser<'cmd> {
11531159
));
11541160
}
11551161
self.start_custom_arg(matcher, arg, source);
1156-
ok!(self.push_arg_values(arg, raw_vals, matcher));
1162+
ok!(self.push_arg_values(arg, raw_vals, source, matcher));
11571163
if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
11581164
debug!(
11591165
"Parser::react not enough values passed in, leaving it to the validator to complain",
@@ -1170,7 +1176,7 @@ impl<'cmd> Parser<'cmd> {
11701176
debug!("Parser::react: cur_idx:={}", self.cur_idx.get());
11711177
}
11721178
self.start_custom_arg(matcher, arg, source);
1173-
ok!(self.push_arg_values(arg, raw_vals, matcher));
1179+
ok!(self.push_arg_values(arg, raw_vals, source, matcher));
11741180
if cfg!(debug_assertions) && matcher.needs_more_vals(arg) {
11751181
debug!(
11761182
"Parser::react not enough values passed in, leaving it to the validator to complain",
@@ -1196,7 +1202,7 @@ impl<'cmd> Parser<'cmd> {
11961202
));
11971203
}
11981204
self.start_custom_arg(matcher, arg, source);
1199-
ok!(self.push_arg_values(arg, raw_vals, matcher));
1205+
ok!(self.push_arg_values(arg, raw_vals, source, matcher));
12001206
Ok(ParseResult::ValuesDone)
12011207
}
12021208
ArgAction::SetFalse => {
@@ -1217,7 +1223,7 @@ impl<'cmd> Parser<'cmd> {
12171223
));
12181224
}
12191225
self.start_custom_arg(matcher, arg, source);
1220-
ok!(self.push_arg_values(arg, raw_vals, matcher));
1226+
ok!(self.push_arg_values(arg, raw_vals, source, matcher));
12211227
Ok(ParseResult::ValuesDone)
12221228
}
12231229
ArgAction::Count => {
@@ -1233,7 +1239,7 @@ impl<'cmd> Parser<'cmd> {
12331239

12341240
matcher.remove(arg.get_id());
12351241
self.start_custom_arg(matcher, arg, source);
1236-
ok!(self.push_arg_values(arg, raw_vals, matcher));
1242+
ok!(self.push_arg_values(arg, raw_vals, source, matcher));
12371243
Ok(ParseResult::ValuesDone)
12381244
}
12391245
ArgAction::Help => {

0 commit comments

Comments
 (0)