From 56135f3ff3c2bd8c5a403e26f779cfd488ec3d33 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Fri, 18 Aug 2023 14:29:37 -0500 Subject: [PATCH] fix(builder): UnknownValueParser shouldn't error on flag absense Fixes #5079 --- clap_builder/src/builder/value_parser.rs | 67 +++++++++++++++--------- tests/builder/error.rs | 2 +- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/clap_builder/src/builder/value_parser.rs b/clap_builder/src/builder/value_parser.rs index 38fbb57f..1f0ef925 100644 --- a/clap_builder/src/builder/value_parser.rs +++ b/clap_builder/src/builder/value_parser.rs @@ -2228,32 +2228,49 @@ impl TypedValueParser for UnknownArgumentValueParser { &self, cmd: &crate::Command, arg: Option<&crate::Arg>, - _value: &std::ffi::OsStr, + value: &std::ffi::OsStr, ) -> Result { - let arg = match arg { - Some(arg) => arg.to_string(), - None => "..".to_owned(), - }; - let err = crate::Error::unknown_argument( - cmd, - arg, - self.arg.as_ref().map(|s| (s.as_str().to_owned(), None)), - false, - crate::output::Usage::new(cmd).create_usage_with_title(&[]), - ); - #[cfg(feature = "error-context")] - let err = { - debug_assert_eq!( - err.get(crate::error::ContextKind::Suggested), - None, - "Assuming `Error::unknown_argument` doesn't apply any `Suggested` so we can without caution" - ); - err.insert_context_unchecked( - crate::error::ContextKind::Suggested, - crate::error::ContextValue::StyledStrs(self.suggestions.clone()), - ) - }; - Err(err) + TypedValueParser::parse_ref_(self, cmd, arg, value, ValueSource::CommandLine) + } + + fn parse_ref_( + &self, + cmd: &crate::Command, + arg: Option<&crate::Arg>, + _value: &std::ffi::OsStr, + source: ValueSource, + ) -> Result { + match source { + ValueSource::DefaultValue => { + TypedValueParser::parse_ref_(&StringValueParser::new(), cmd, arg, _value, source) + } + ValueSource::EnvVariable | ValueSource::CommandLine => { + let arg = match arg { + Some(arg) => arg.to_string(), + None => "..".to_owned(), + }; + let err = crate::Error::unknown_argument( + cmd, + arg, + self.arg.as_ref().map(|s| (s.as_str().to_owned(), None)), + false, + crate::output::Usage::new(cmd).create_usage_with_title(&[]), + ); + #[cfg(feature = "error-context")] + let err = { + debug_assert_eq!( + err.get(crate::error::ContextKind::Suggested), + None, + "Assuming `Error::unknown_argument` doesn't apply any `Suggested` so we can without caution" + ); + err.insert_context_unchecked( + crate::error::ContextKind::Suggested, + crate::error::ContextValue::StyledStrs(self.suggestions.clone()), + ) + }; + Err(err) + } + } } } diff --git a/tests/builder/error.rs b/tests/builder/error.rs index bd94c6bd..833a614d 100644 --- a/tests/builder/error.rs +++ b/tests/builder/error.rs @@ -263,7 +263,7 @@ fn unknown_argument_flag() { ]); let res = cmd.clone().try_get_matches_from(["test"]); - assert!(res.is_err()); + assert!(res.is_ok()); let res = cmd.try_get_matches_from(["test", "--ignored"]); assert!(res.is_err());