Skip to main content

Module match_arg

Module match_arg 

Source
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_arg argument error, shared by the wrappers preamble’s .miniextendr_match_arg / .miniextendr_match_arg_several (crate::registry::ARG_CHECK_HELPERS, built with concat!) and MatchArgError::arg_error, so R and Rust word these errors from one source (#1741). The generated conversion of a match_arg type words its error with arg_error too (#1767). or and alias_for are 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 their listed argument. It expands to string literals.

Structs§

EitherArmProbe 👻
Reads TryFromSexp::CHARACTER_ONLY of the R arm of an Either<T, R> choice parameter without requiring R: TryFromSexp.
MatchArgAlias
One entry of MatchArg::ALIASES: alias, another spelling of the choice choice, and whether the errors that list the choices name it.

Enums§

MatchArgError
Error type for MatchArg conversion failures.

Traits§

EitherArmProbeFallback 👻
The fallback of EitherArmProbe for an R without TryFromSexp: the check passes, and the decode reports the missing impl.
MatchArg
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>, or one or more of "fast", "slow"<suffix> for a several_ok parameter (several), quoted as one_of quotes, the listed aliases between the choices and the suffix (one of "fast", "slow" (or "quick" for "fast"), or a number). The generated argument error of a match_arg / choices parameter on Either<T, R> passes the other accepted values as suffix (, or a data frame), in the words of its @param line; an Either whose arms both refused a value joins them with it too.
choices_sexp
Build an R character vector (STRSXP) from the choices of a MatchArg type.
default_first 🔒
The choices of a match_arg parameter’s R formal: choices with the default moved to the front and the others after it in their order ("Safe" in "Fast", "Safe", "Debug" gives "Safe", "Fast", "Debug"), or None when is_default holds for no choice.
escape_r_string
Escape a Rust &str for embedding inside an R double-quoted string literal.
factor_label 🔒
The label of element i of a factor (None for 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 NULL and the formal itself select.
is_formal 🔒
Whether the len strings label(i) (None for NA) are formal, 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 in choices (MatchArg::CHOICES, the order of the variants), then their order in aliases. quote quotes 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_arg check (.miniextendr_match_arg), which are those of base::match.arg(arg, choices):
match_arg_missing_or
The Missing<_> layer of a choice parameter (#1551): the missing-argument sentinel is Missing::Absent, anything else (NULL included) is decoded by inner and becomes Missing::Present.
match_arg_null_or
The Option<_> layer of a choice parameter: NULL is None, anything else is decoded by inner and becomes Some.
match_arg_option_from_sexp
Optional form of match_arg_from_sexp for Option<T> parameters (#1473).
match_arg_param
Match a choice argument a body received as a raw SEXP exactly as the generated wrapper matches a #[miniextendr(match_arg)] parameter, and with the same error.
match_arg_param_with_default
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).
match_arg_vec_from_sexp
Extract multiple strings from an R SEXP (STRSXP) and match each against the choices of a MatchArg type.
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 MatchArg type: a choice typed exactly, then an alias typed exactly (MatchArg::ALIASES), then a unique prefix of a choice.
match_formal 🔒
match_arg_from_sexp for a parameter whose R formal is formal, a permutation of T::CHOICES: its first element is what NULL and the formal itself select. Matching a string does not depend on the order.
match_na 🔒
NA as 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 is MatchArgError::IsNa. No alias maps it: the wrapper looks aliases up with match(), which never matches NA to "NA".
match_string 🔒
match_choice with the aliases aliases.
one_of
one of "fast", "slow": what a match_arg / choices value 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 listed aliases follow the choices (one of "fast", "slow" (or "quick" for "fast")).
r_quote 🔒
"x": a string quoted as R’s dQuote(x, FALSE) quotes it, without escapes, as the match_arg check’s message quotes the choices.
sexp_err_to_match_arg_err 🔒
Map a SexpError from a string TryFromSexp conversion into a MatchArgError.