Expand description
match.arg-style string conversion for enums.
Provides the MatchArg trait for converting Rust enums to/from R character
strings with partial matching, like R’s match.arg().
Use #[derive(MatchArg)] on C-style enums to auto-generate the implementation.
match.arg-style enum conversion for R string arguments.
This module provides the MatchArg trait for converting between Rust
fieldless enums and R character strings with match.arg semantics
(exact match or unique partial matching).
§Usage
use miniextendr_api::MatchArg;
#[derive(Copy, Clone, MatchArg)]
#[match_arg(rename_all = "snake_case")]
enum Mode {
Fast,
Safe,
Debug,
}
#[miniextendr]
fn run(#[miniextendr(match_arg)] mode: Mode) -> String {
format!("{mode:?}")
}The generated R wrapper uses base::match.arg() for validation before
the main .Call(), giving users familiar R error messages and partial
matching.
An Option<T> parameter (#[miniextendr(match_arg)] mode: Option<Mode>)
is the optional form: the R formal defaults to NULL, NULL converts to
None, and any other value is matched as usual. The generated C wrapper
decodes it with match_arg_option_from_sexp (there is no
TryFromSexp for Option<T> blanket: that slot belongs to the newtype
forwarding impls in crate::newtype, and a downstream crate cannot add
one for its own enum under the orphan rule), so a hand-written MatchArg
impl needs nothing extra.
A Missing<..> around the parameter type (Missing<T>,
Missing<Option<T>>, Missing<Vec<T>> for several_ok) keeps the choice
vector as the R formal and reports an omitted argument as
Missing::Absent (#1551), as it does that formal passed whole for a
single choice (#2152); the C wrapper decodes it with
match_arg_missing_or around the decoder of the inner type.
With the either feature, Either<T, R> takes a choice or a value of
another kind: character or factor input is matched and becomes Left(T),
anything else converts to R (match_arg_either_or). A several_ok list
takes the same split as Either<Vec<T>, R> or Either<Box<[T]>, R>
(#1612): character or factor input is matched element by element and
becomes Left(Vec<T>), anything else converts to R.
MatchArg::ALIASES (#[match_arg(alias = "grey")] on a variant) adds
other spellings of a choice, matched only when typed in full, by every
matcher on both sides. An error that lists the choices names them after
the choices ((or "grey" for "gray")), unless an alias opts out with
listed = false; the formal, the usage and the @param line list the
choices only.
several_ok parameters are validated strictly on the R side: every element
has to match a choice, and NULL selects every choice (the same fallback
match_arg_vec_from_sexp applies). Under Either, NULL is not a
choice: it goes to R (or is None under Option<Either<..>>).
Macros§
- match_
arg_ 🔒wording - The words of a
match_argargument error, shared by the wrappers preamble’s.miniextendr_match_arg/.miniextendr_match_arg_several(crate::registry::ARG_CHECK_HELPERS, built withconcat!) andMatchArgError::arg_error, so R and Rust word these errors from one source (#1741). The generated conversion of amatch_argtype words its error witharg_errortoo (#1767).orandalias_forare the words of the clause naming the listed aliases (listed_aliases_clause, #2148), which the wrappers writer renders in Rust and passes to the R helpers as theirlistedargument. It expands to string literals.
Structs§
- Either
ArmProbe 👻 - Reads
TryFromSexp::CHARACTER_ONLYof theRarm of anEither<T, R>choice parameter without requiringR: TryFromSexp. - Match
ArgAlias - One entry of
MatchArg::ALIASES:alias, another spelling of the choicechoice, and whether the errors that list the choices name it.
Enums§
- Match
ArgError - Error type for
MatchArgconversion failures.
Traits§
- Either
ArmProbe 👻Fallback - The fallback of
EitherArmProbefor anRwithoutTryFromSexp: the check passes, and the decode reports the missing impl. - Match
Arg - Trait for enum types that support
match.arg-style string conversion.
Functions§
- alias_
problems 🔒 - What is wrong with the aliases of a type whose choices are
choices, one sentence per bad alias, in order (empty when they are fine): an alias that is empty or"NA", a choice, given twice, or a prefix of a choice other than its own (typing it would select something else than without the alias), and a target that is not a choice.#[derive(MatchArg)]refuses the same at compile time, with the same words; the wrappers writer checks a hand-written impl with this (crate::registry::match_arg_aliases_arg). - choice_
expectation 👻 one of "fast", "slow"<suffix>, orone or more of "fast", "slow"<suffix>for aseveral_okparameter (several), quoted asone_ofquotes, the listedaliasesbetween the choices and the suffix (one of "fast", "slow" (or "quick" for "fast"), or a number). The generated argument error of amatch_arg/choicesparameter onEither<T, R>passes the other accepted values assuffix(, or a data frame), in the words of its@paramline; anEitherwhose arms both refused a value joins them with it too.- choices_
sexp - Build an R character vector (STRSXP) from the choices of a
MatchArgtype. - default_
first 🔒 - The choices of a
match_argparameter’s R formal:choiceswith the default moved to the front and the others after it in their order ("Safe"in"Fast", "Safe", "Debug"gives"Safe", "Fast", "Debug"), orNonewhenis_defaultholds for no choice. - escape_
r_ string - Escape a Rust
&strfor embedding inside an R double-quoted string literal. - factor_
label 🔒 - The label of element
iof a factor (Nonefor a missing code or one outside the levels). - factor_
to_ 🔒choice - A factor as a choice: read as its labels, like
as.character(). - first_
choice 🔒 - The first choice of the formal: what
NULLand the formal itself select. - is_
formal 🔒 - Whether the
lenstringslabel(i)(NoneforNA) areformal, in order: the formal default of a choice parameter, which an omitted argument evaluates to. - listed_
aliases_ 🔒clause - The text that names the listed aliases after the choices of a message: a
space, then
(or "oral" for "extravascular", "grey" for "gray");""when no alias is listed (#2148). The aliases follow the order of their choices inchoices(MatchArg::CHOICES, the order of the variants), then their order inaliases.quotequotes each alias and choice, as the message quotes the choices before it. - match_
arg_ from_ sexp - Match one choice argument with the semantics of the generated wrapper’s
match_argcheck (.miniextendr_match_arg), which are those ofbase::match.arg(arg, choices): - match_
arg_ missing_ or - The
Missing<_>layer of a choice parameter (#1551): the missing-argument sentinel isMissing::Absent, anything else (NULLincluded) is decoded byinnerand becomesMissing::Present. - match_
arg_ null_ or - The
Option<_>layer of a choice parameter:NULLisNone, anything else is decoded byinnerand becomesSome. - match_
arg_ option_ from_ sexp - Optional form of
match_arg_from_sexpforOption<T>parameters (#1473). - match_
arg_ param - Match a choice argument a body received as a raw
SEXPexactly as the generated wrapper matches a#[miniextendr(match_arg)]parameter, and with the same error. - match_
arg_ param_ with_ default match_arg_paramfor a choice argument whose R formal listsdefaultfirst: 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).- match_
arg_ vec_ from_ sexp - Extract multiple strings from an R SEXP (STRSXP) and match each against
the choices of a
MatchArgtype. - match_
arg_ vec_ into_ sexp - Convert a
Vec<T: MatchArg>to an R character vector (STRSXP). - match_
choice 🔒 - Match a string against the choices of a
MatchArgtype: a choice typed exactly, then an alias typed exactly (MatchArg::ALIASES), then a unique prefix of a choice. - match_
formal 🔒 match_arg_from_sexpfor a parameter whose R formal isformal, a permutation ofT::CHOICES: its first element is whatNULLand the formal itself select. Matching a string does not depend on the order.- match_
na 🔒 NAas a choice:pmatch(), and so the wrapper’s check, matches it as the string"NA", so a choice that is"NA"or the only one starting with it is selected. Anything else isMatchArgError::IsNa. No alias maps it: the wrapper looks aliases up withmatch(), which never matchesNAto"NA".- match_
string 🔒 match_choicewith the aliasesaliases.- one_of
one of "fast", "slow": what amatch_arg/choicesvalue must be, in the words of a conversion’s argument error that names it beside other accepted values ('x' must be one of "oral", "bolus", or a single double: got logical, #1594). The listedaliasesfollow the choices (one of "fast", "slow" (or "quick" for "fast")).- r_quote 🔒
"x": a string quoted as R’sdQuote(x, FALSE)quotes it, without escapes, as thematch_argcheck’s message quotes the choices.- sexp_
err_ 🔒to_ match_ arg_ err - Map a
SexpErrorfrom a stringTryFromSexpconversion into aMatchArgError.