Skip to main content

RustConversionBuilder

Struct RustConversionBuilder 

Source
pub struct RustConversionBuilder {
    inferred_types: bool,
    coerce_all: bool,
    coerce_params: Vec<String>,
    strict: bool,
    match_arg_several_ok_params: Vec<String>,
    layered_choice_params: Vec<(String, ChoiceLeaf)>,
    no_na_params: Vec<(String, Option<String>)>,
    param_markers: Vec<(String, Vec<ParamMarker>)>,
    conversion_error_class: Vec<String>,
    unevaluated_args: bool,
    self_type: Option<Type>,
    formals: Formals,
}
Expand description

Builder for generating Rust conversion statements from R SEXP parameters.

Handles:

  • Unit types () → identity binding
  • &Dots → special wrapper with storage
  • Slices &[T] → TryFromSexp
  • &str → String + Borrow (for worker thread compatibility)
  • Scalar references → DATAPTR_RO_unchecked
  • Coercion → multi-source numeric conversion (incl. widened native i32/f64) or logical/integer bool conversion
  • Default → TryFromSexp

Fields§

§inferred_types: bool

Infer copied trait signature types from a concrete method item.

§coerce_all: bool

Enable coercion for all parameters

§coerce_params: Vec<String>

Parameter names that should use coercion

§strict: bool

Enable strict input conversion for lossy types

§match_arg_several_ok_params: Vec<String>

Parameter names with match_arg + several_ok — use match_arg_vec_from_sexp instead of TryFromSexp.

§layered_choice_params: Vec<(String, ChoiceLeaf)>

Choice parameters whose type wraps the choice in Missing / Option layers (#1473, #1551), with the kind of their innermost value. Decoded by layered_choice_expr instead of TryFromSexp.

§no_na_params: Vec<(String, Option<String>)>

no_na parameters (Rust name) with the author’s no_na(message = ..), if any: their converted value is checked right after the conversion (see Self::with_no_na).

§param_markers: Vec<(String, Vec<ParamMarker>)>

Parameters (Rust name) declared with parameter markers (Checked<T> / Unchecked<T>, #1566), outermost first: the inner type converts, then the value is wrapped (see Self::with_param_markers).

§conversion_error_class: Vec<String>

The crate’s conversion_error_class ([package.metadata.miniextendr]), appended to every conversion condition’s class vector.

§unevaluated_args: bool

Whether Quoted / Quosure parameters are bound (a standalone fn, whose R wrapper passes them unevaluated, #1835). Elsewhere they are a compile error.

§self_type: Option<Type>

The impl’s type, for Self in a method’s borrowed external argument (other: &Self): the wrapper is a free function.

§formals: Formals

The R formal of each parameter (#1842): what a conversion condition names the argument (see Self::with_formals).

Implementations§

Source§

impl RustConversionBuilder

Source

pub fn new() -> Self

Create a new conversion builder, carrying the crate-level conversion_error_class from the manifest (empty when unset).

Source

pub(crate) fn with_inferred_types(self) -> Self

Source

pub fn with_self_type(self, self_type: Type) -> Self

Name the impl’s type for Self in borrowed external arguments.

Source

fn external_arg(&self, pat_type: &PatType) -> Option<ExternalArg>

The borrowed external argument (&T / &mut T / a view, #2106) pat_type declares. A parameter marker’s parameter is none: the marker rebinds the converted value, which a borrowed argument only gets after every conversion.

Source

pub fn with_unevaluated_args(self) -> Self

Bind Quoted / Quosure parameters (#1835): set for standalone fns, whose R wrapper passes those arguments unevaluated (r_wrapper_builder::RArgumentBuilder::build_call_args_vec). Without it such a parameter is a compile error.

Source

pub fn with_coerce_all(self) -> Self

Enable coercion for all parameters.

Source

pub fn with_coerce_param(self, param_name: String) -> Self

Add a single parameter name that should use coercion.

param_name is matched against the identifier in the function signature. Can be called multiple times to add several parameters.

Source

pub fn with_strict(self) -> Self

Enable strict input conversion for lossy types (i64/u64/isize/usize + Vec variants).

Source

pub fn with_match_arg_several_ok(self, param_name: String) -> Self

Mark a parameter as match_arg + several_ok — uses match_arg_vec_from_sexp instead of TryFromSexp for converting STRSXP → Vec<EnumType>.

Source

pub fn with_layered_choice(self, param_name: String, leaf: ChoiceLeaf) -> Self

Mark a choice parameter whose type wraps the choice in Missing / Option layers (#1473, #1551): it is decoded layer by layer with the miniextendr_api::match_arg_* helpers (see layered_choice_expr) instead of TryFromSexp. There is no TryFromSexp for Option<T> a downstream crate could provide for its own enum (orphan rule), and a T: MatchArg blanket would collide with the newtype blanket in miniextendr_api::newtype, so the wrapper calls the helpers directly.

Source

pub fn with_no_na(self, param_name: String, message: Option<String>) -> Self

Mark a #[miniextendr(no_na)] parameter (param_name is its Rust name), with the author’s no_na(message = "...") if given.

The R guard !anyNA(x) runs first; a type can still read an input as missing that anyNA() does not see (the reading markers AsNumeric* / AsCharacter* read the text "NA" or a blank string as NA). So when the parameter converts through plain TryFromSexp, the converted value is asked TryFromSexp::__mx_has_na right after its binding, and a refusal returns the R guard’s own condition (see no_na_value_stmt). No type is named: Rust resolves the call on the value’s real type, so aliases and derived newtypes of a marker are checked too, and for any other type the default false optimises out. The reference arms (&T, &[T], &str) emit no check and keep only the R guard: they convert through the reference type’s own impl, and no reading marker converts by reference.

An Either parameter (also under Missing) has no R guard (r_preconditions::no_na_checked_after_conversion). Its value is asked TryFromSexp::__mx_input_has_na with the input SEXP instead: the arm the value converted to makes the guard’s anyNA() check on the input in Rust, then its own __mx_has_na, and a DataFrame arm refuses nothing (also behind a derived newtype or Result<_, ()>, which forward the call).

Source

pub fn with_formals(self, formals: Formals) -> Self

Name each argument by its R formal (#1842) in its conversion condition: the message’s '<p>' and e$param. Without a declared formal, the Rust name without leading underscores.

Source

pub fn with_param_markers( self, param_name: String, markers: Vec<ParamMarker>, ) -> Self

Mark a parameter (param_name is its Rust name) whose declared type wraps the one it converts as in parameter markers (Checked<T> / Unchecked<T>, #1566), outermost first. The pat_type this builder sees holds the inner type, so the conversion and its failure context (e$rust_type) are the inner type’s; after the parameter’s last statement (the borrow on the split worker path, else the conversion or its no_na check) the value is rebound through each marker’s from_inner, innermost first, so the call receives the declared type.

Source

fn marker_rebind(&self, pat_type: &PatType) -> Option<TokenStream>

The rebinding of a marked parameter’s converted value (see Self::with_param_markers), or None for an unmarked parameter.

Source

fn should_coerce(&self, param_name: &str) -> bool

Check if a parameter should use coercion.

Returns true if coerce_all is set or param_name appears in the per-parameter list.

Source

pub(crate) fn native_borrow_metadata( &self, pat_type: &PatType, sexp_ident: &Ident, ) -> Option<TokenStream>

Describe only the conversion actually used for this argument.

Special paths can have no TryFromSexp impl for the declared type. Omit their metadata queries at codegen time; a runtime branch still typechecks.

Source

fn borrow_metadata_for( &self, ty: &Type, name: &Ident, rooted: bool, ) -> TokenStream

Source

fn unevaluated_binding( &self, ident: &Ident, sexp_ident: &Ident, r_name: &str, ty: &Type, param: UnevaluatedParam, ) -> TokenStream

The binding of a Quoted / Quosure parameter (#1835) from the argument its R wrapper passed: the capture, or the missing-argument sentinel. Missing<..> reads the sentinel as Missing::Absent; a bare marker returns R’s own error for a missing argument as a conversion condition naming the parameter (e$param). The marker borrows the argument SEXP (rooted by .Call() for the call), so it cannot outlive the call.

Source

fn conversion_stmt( &self, try_expr: TokenStream, ctx: &ArgContext, ident: &Ident, ty: &Type, span: Span, ) -> TokenStream

Generate a conversion expression that returns a tagged condition SEXP on failure.

The R wrapper inspects .val and raises a structured rust_* condition; the return happens from inside the C wrapper body before any further conversion.

  • try_expr: The Result<T, E>-producing expression
  • ctx: The argument’s R-facing failure context (ArgContext): the message prefix, e$param and e$rust_type
  • ident: The binding name for the converted value
  • ty: The target Rust type (for the let binding). The annotation is load-bearing: the Err arm probes the error type by method call (conversion_err_arm), which needs that type known at that point.
  • span: Source span for error reporting
Source

pub fn build_conversion( &self, pat_type: &PatType, sexp_ident: &Ident, ) -> Vec<TokenStream>

Generate conversion statement for a single parameter.

This is the non-split variant: owned conversions and borrow statements are concatenated into a single list, suitable for main-thread execution where everything runs in the same scope.

  • pat_type: the typed pattern from the function signature (e.g., x: i32).
  • sexp_ident: the identifier of the raw SEXP variable holding the R argument.

Returns a flat list of let binding statements that convert sexp_ident into the Rust type declared in pat_type.

Source

pub fn build_conversion_split( &self, pat_type: &PatType, sexp_ident: &Ident, ) -> (Vec<TokenStream>, Vec<TokenStream>)

Generate conversion statements split into two phases for worker thread execution.

&str, Option<&str>, Vec<&str> and Vec<Option<&str>> first convert to the corresponding owned strings on R’s main thread. The worker closure owns that storage and creates the borrows inside it. Other conversions without a separate borrow use only the first vec.

  • pat_type: the typed pattern from the function signature (e.g., s: &str).
  • sexp_ident: the identifier of the raw SEXP variable holding the R argument.

Returns (owned_conversions, borrow_statements) where each element is a list of let binding token streams.

Source

fn build_conversion_split_inner( &self, pat_type: &PatType, sexp_ident: &Ident, root_shared_inputs: bool, ) -> (Vec<TokenStream>, Vec<TokenStream>)

Inner implementation of Self::build_conversion_split.

root_shared_inputs selects the main-thread shared-borrow path:

  • true (main-thread, single-scope): emit a direct zero-copy &str borrow over R’s CHARSXP pool via TryFromRoot — no String allocation. Shared native references use the same root-bound path; its lifetime prevents the result from escaping the call as a static reference.
  • false (worker): convert borrowed strings, including optional and vector forms, to owned storage on main; borrow only inside the worker.
Source

pub fn build_conversions( &self, inputs: &Punctuated<FnArg, Comma>, sexp_idents: &[Ident], ) -> Vec<TokenStream>

Generate conversion statements for all parameters in a function signature.

Iterates over inputs (the function’s parameter list) paired with sexp_idents (the corresponding SEXP variable names), calling build_conversion for each typed parameter. Receiver parameters (self) are silently skipped.

Returns a flat list of all conversion statements, in parameter order.

Trait Implementations§

Source§

impl Default for RustConversionBuilder

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> SizeHint for T
where T: ?Sized,

Source§

default fn lower_bound(&self) -> usize

🔬This is a nightly-only experimental API. (core_io_internals)
Returns a lower bound on the number of elements this container-like item contains. For example, an array [u8; 12] could return any value between 0 and 12 inclusively as a correct implementation. Read more
Source§

default fn upper_bound(&self) -> Option<usize>

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an upper bound on the number of elements this container-like item contains if it can be determined, otherwise None. Read more
Source§

final fn size_hint(&self) -> (usize, Option<usize>)

🔬This is a nightly-only experimental API. (core_io_internals)
Returns an estimate for the number of elements this container like type contains. Read more
Source§

impl<T> SizedTypeProperties for T

Source§

#[doc(hidden)]
const SIZE: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const ALIGNMENT: Alignment = _

🔬This is a nightly-only experimental API. (ptr_alignment_type)
Source§

#[doc(hidden)]
const IS_ZST: bool = _

🔬This is a nightly-only experimental API. (sized_type_properties)
true if this type requires no storage. false if its size is greater than zero. Read more
Source§

#[doc(hidden)]
const LAYOUT: Layout = _

🔬This is a nightly-only experimental API. (sized_type_properties)
Source§

#[doc(hidden)]
const MAX_SLICE_LEN: usize = _

🔬This is a nightly-only experimental API. (sized_type_properties)
The largest safe length for a [Self]. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 520 bytes