diff --git a/docs/design/problems_with_clap.md b/docs/design/problems_with_clap.md index d3c8774..308b2ac 100644 --- a/docs/design/problems_with_clap.md +++ b/docs/design/problems_with_clap.md @@ -108,7 +108,7 @@ uutils and when we opened as issue for it, it was discarded. This makes sense from `clap`'s perspective, but it shows that the priorities between `clap` and uutils diverge. -## Problem 6: It's stringly typed +## Problem 7: It's stringly typed `clap`'s arguments are identified by strings. This leads to code like this: @@ -135,14 +135,14 @@ deal, but a bit annoying. Of course, we wouldn't have this problem if we were able to use the derive API. -## Problem 7: Reading help string from a file +## Problem 8: Reading help string from a file In `uutils` our help strings can get quite long. Therefore, we like to extract those to an external file. With `clap` this means that we need to do some custom preprocessing on this file to extract the information for the several pieces of the help string that `clap` supports. -## Problem 8: No markdown support +## Problem 9: No markdown support Granted, this is not really a problem, but more of a nice-to-have. We have online documentation for the utils, based on the help strings and these are @@ -150,6 +150,16 @@ rendered from markdown. Ideally, our argument parser supports markdown too, so that we can have nicely rendered help strings which have (roughly) the same appearance in the terminal and online. +## Problem 10: No position-dependent argument-error prioritization + +This is the question of which error to print if both `-A` and `-B` are given, +and both are individually an error somehow. In case of the GNU tools, only the +first error is printed, and then the program is aborted. + +This also is not really a problem, but since it can be reasonably easily +achieved by simply raising an error during argument application, this enables +matching more closely the exact behavior of the GNU tools. + ## Good things about `clap` Alright, enough problems. Let's praise `clap` a bit, because it's an excellent diff --git a/tests/flags.rs b/tests/flags.rs index b292c1b..207c2e1 100644 --- a/tests/flags.rs +++ b/tests/flags.rs @@ -517,3 +517,36 @@ fn enum_flag() { SomeEnum::Baz, ); } + +#[test] +fn simple_error() { + #[derive(Arguments)] + enum Arg { + #[arg("-f", "--foo")] + Foo, + } + + #[derive(Debug, Default)] + struct Settings {} + + impl Options for Settings { + fn apply(&mut self, _arg: Arg) -> Result<(), uutils_args::Error> { + Err(uutils_args::Error { + exit_code: 42, + kind: uutils_args::ErrorKind::UnexpectedArgument(format!( + "This is an example error" + )), + }) + } + } + + let settings_or_error = Settings::default().parse(["test", "-f"]); + let the_error = settings_or_error.expect_err("should have propagated error"); + assert_eq!(the_error.exit_code, 42); + match the_error.kind { + uutils_args::ErrorKind::UnexpectedArgument(err_str) => { + assert_eq!(err_str, "This is an example error") + } + _ => panic!("wrong error kind: {:?}", the_error.kind), + } +}