Skip to main content

Module newtype_derive

Module newtype_derive 

Source
Expand description

#[derive(TryFromSexp)] / #[derive(IntoR)] — forward R↔Rust conversions from a single-field newtype to its inner type. #[derive(IsNA)] uses the same parser to forward native missing-value detection.

For a newtype struct UserId(Uuid) (or struct UserId { inner: Uuid }):

  • #[derive(TryFromSexp)] generates the R → Rust direction: a scalar TryFromSexp impl that forwards to the inner type, plus a miniextendr_api::TryFromSexpElement marker impl. The marker lets the container blankets in miniextendr_api::newtype light up Vec<UserId> / Option<UserId> / Vec<Option<UserId>> — see issues #844 and #1766.
  • #[derive(IntoR)] generates the Rust → R direction: a scalar IntoR impl that forwards to the inner type, plus miniextendr_api::IntoRNewtype (for Option / Vec<Option>) and a concrete miniextendr_api::IntoRVecElement impl (for Vec).

Direction is chosen by which derive you list. Some inner types are convertible in only one direction (a compiled regex::Regex reads from R but cannot be written back): derive only TryFromSexp for those.

ⓘ
#[derive(TryFromSexp)]            // R -> Rust only
struct Pattern(regex::Regex);

#[derive(TryFromSexp, IntoR)]     // round-trip
struct UserId(uuid::Uuid);

#[derive(TryFromSexp)] takes one attribute, on the struct: #[try_from_sexp(validate = path::to::check)], with check a fn(SEXP) -> Result<(), E> and E: Into<SexpError> (an RError or any RConditionData type for a classed refusal). It becomes TryFromSexpElement::check_sexp, which the scalar impl and every container run on the R value before the inner type reads it (#1815). The scalar impl’s error is then SexpError, so the inner type’s error must convert into it.

Do not derive both IntoR and MatchArg on the same type: both would feed the single IntoR for Vec<T> blanket slot and collide (E0119).

Structs§

Newtype 🔒
The single field of a newtype: its inner type plus how to wrap/unwrap it.
TryFromSexpOptions 🔒
The #[try_from_sexp(...)] options of #[derive(TryFromSexp)].

Functions§

derive_into_r
#[derive(IntoR)]: scalar forwarding IntoR + IntoRNewtype marker (for Option/Vec<Option> blankets) + concrete IntoRVecElement (for Vec).
derive_is_na
#[derive(IsNA)]: delegate native missing-value detection to the field.
derive_try_from_sexp
#[derive(TryFromSexp)]: scalar forwarding TryFromSexp + TryFromSexpElement marker.
expectation_const 🔒
The newtype’s TryFromSexp::__MX_EXPECTATION: what an argument of the inner type must be, in R terms, so a newtype parameter or Either arm reads as its inner type does (struct Dose(AsNumeric): a single number). The macro’s own wording when it knows the inner type (crate::r_preconditions::conversion_expectation), else the inner type’s constant, which a newtype of a newtype carries through.
parse_newtype 🔒
parse_try_from_sexp_options 🔒
Read the struct’s #[try_from_sexp(...)] attributes. The only key is validate = path; any other key, a repeated validate, or the attribute on the field is a spanned error.
where_with 🔒
Build a where clause that merges the struct’s existing predicates with extra predicates (the Inner: Trait bounds the forwarding impl requires).