pub fn match_arg_param_with_default<T: MatchArg>(
sexp: SEXP,
param: &str,
default: T,
) -> Result<T, ArgError>Expand description
match_arg_param for a choice argument whose R formal lists default
first: the formal of a #[miniextendr(match_arg, default = "...")]
parameter, which moves its default to the front and keeps the other
choices in their order (#1767).
The formal’s order decides three things, and here they follow the formal
rather than T::CHOICES: the choice NULL selects, the vector that counts
as the formal itself (what an omitted argument evaluates to), and the
order of the choices in the message. For
#[miniextendr(match_arg, default = "\"Safe\"")] mode: Mode with
Mode::CHOICES "Fast", "Safe", "Debug", the formal is
c("Safe", "Fast", "Debug"):
| Input | match_arg_param | match_arg_param_with_default(.., Mode::Safe) |
|---|---|---|
NULL | Fast | Safe |
c("Safe", "Fast", "Debug") | 'mode' must be of length 1 | Safe |
c("Fast", "Safe", "Debug") | Fast | 'mode' must be of length 1 |
"zzz" | 'mode' should be one of "Fast", "Safe", "Debug" | 'mode' should be one of "Safe", "Fast", "Debug" |
Matching a string is the same either way. The wrappers writer orders the formal with the same code, so the two agree on every input.
default is a T, not its string or its position: it is always one of
the choices, a misspelled default does not compile, and a renamed or
reordered choice moves with it.
#[miniextendr]
pub fn run(mode: SEXP) -> String {
let mode: Mode = match_arg_param_with_default(mode, "mode", Mode::Safe)
.unwrap_or_else(|e| e.raise());
format!("{mode:?}")
}