Skip to main content

CWrapperContext

Struct CWrapperContext 

Source
pub struct CWrapperContext {
Show 23 fields pub fn_ident: Ident, pub c_ident: Ident, pub r_wrapper_const: Ident, pub inputs: Punctuated<FnArg, Comma>, pub output: ReturnType, pub pre_call: Vec<TokenStream>, pub call_expr: TokenStream, pub thread_strategy: ThreadStrategy, pub return_handling: ReturnHandling, pub coerce_all: bool, pub coerce_params: Vec<String>, pub check_interrupt: bool, pub rng: bool, pub cfg_attrs: Vec<Attribute>, pub type_context: Option<Ident>, pub has_self: bool, pub call_method_def_ident: Option<Ident>, pub strict: bool, pub match_arg_several_ok_params: Vec<String>, pub preserve_param_names: bool, pub vis: Visibility, pub generics: Generics, pub skip_wrapper: bool,
}
Expand description

All information needed to generate a C wrapper function for an R-exported Rust item.

This struct abstracts over the differences between standalone #[miniextendr] functions and impl block methods (R6, S3, S4, S7, Env). It is constructed via CWrapperContextBuilder and consumed by CWrapperContext::generate, which emits both the extern "C-unwind" wrapper and the corresponding R_CallMethodDef constant.

Fields§

§fn_ident: Ident

Identifier of the original Rust function or method being wrapped.

§c_ident: Ident

Identifier for the generated C wrapper (e.g., C_foo or C_Type__method).

§r_wrapper_const: Ident

Identifier of the R_WRAPPER_* or R_WRAPPERS_IMPL_* const that holds the generated R wrapper code string. Used for rustdoc cross-references.

§inputs: Punctuated<FnArg, Comma>

Function parameters (excluding the self receiver for methods). Each parameter becomes a SEXP argument in the C wrapper signature.

§output: ReturnType

The original Rust return type. Used by strict-mode to inspect whether the inner type is lossy (e.g., i64, u64) and needs checked conversion.

§pre_call: Vec<TokenStream>

Statements emitted before the call expression. For instance methods, this includes extracting self from the ExternalPtr SEXP.

§call_expr: TokenStream

The actual Rust call expression (e.g., my_func(arg0, arg1) or self_ref.method(arg0)). Inserted into the wrapper body after conversions.

§thread_strategy: ThreadStrategy

Whether to run on the main R thread or dispatch to the worker thread.

§return_handling: ReturnHandling

How to convert the Rust return value into a SEXP for R.

§coerce_all: bool

When true, all parameters use coercing conversion (Rf_coerceVector) instead of strict type-matching. Set by #[miniextendr(coerce)].

§coerce_params: Vec<String>

Names of individual parameters that use coercing conversion. Set by #[miniextendr(coerce = "param_name")].

§check_interrupt: bool

When true, emits R_CheckUserInterrupt() before the call expression. Set by #[miniextendr(check_interrupt)].

§rng: bool

When true, wraps the call in GetRNGstate()/PutRNGstate() for R’s random number generator state management. Set by #[miniextendr(rng)].

§cfg_attrs: Vec<Attribute>

#[cfg(...)] attributes from the original item, propagated to the C wrapper and call_method_def constant so they are conditionally compiled.

§type_context: Option<Ident>

For methods: the type identifier (e.g., MyStruct). Used in doc comments and default call_method_def naming. None for standalone functions.

§has_self: bool

Whether the original method has a self receiver. When true, the C wrapper includes a self_sexp parameter before the regular arguments.

§call_method_def_ident: Option<Ident>

Override for the call_method_def constant name. If None, defaults to call_method_def_{type}_{method} (methods) or call_method_def_{fn} (standalone).

§strict: bool

When true, uses checked_into_sexp_* for lossy return types (i64, u64, isize, usize and their Vec variants) instead of regular IntoR::into_sexp. Set by #[miniextendr(strict)].

§match_arg_several_ok_params: Vec<String>

Parameter names with #[miniextendr(match_arg, several_ok)] — use match_arg_vec_from_sexp (instead of TryFromSexp) for the Vec conversion so each element is validated against the enum’s MatchArg::CHOICES.

Scalar match_arg doesn’t need entries here because R-side match.arg() already narrowed the SEXP to a valid choice; the default TryFromSexp for Enum (generated by #[derive(MatchArg)]) decodes it.

§preserve_param_names: bool

When true, preserve original parameter names from inputs in the C wrapper signature instead of renaming to arg_0, arg_1, … The fn path preserves user identifiers for rustdoc visibility; impl method path uses arg_N for safety.

§vis: Visibility

Visibility of the generated extern "C-unwind" wrapper function. Default: syn::Visibility::Inherited (no visibility keyword). Standalone #[miniextendr] fns forward the user’s visibility (pub, pub(crate), etc.).

§generics: Generics

Generic parameters of the wrapped function, emitted on the C wrapper signature as fn #c_ident #generics(...). Default: empty (no generics).

§skip_wrapper: bool

When true, the original Rust fn is already an extern "C-unwind" symbol (user-written). Skip generating the wrapper body but still emit the R_CallMethodDef for registration. The numArgs count excludes the synthetic __miniextendr_call SEXP parameter since the user-written fn doesn’t have it.

Implementations§

Source§

impl CWrapperContext

Source

pub fn builder(fn_ident: Ident, c_ident: Ident) -> CWrapperContextBuilder

Creates a new CWrapperContextBuilder with the given function and C wrapper identifiers.

All other fields start at their defaults (empty/false/None). Use the builder methods to configure the context, then call CWrapperContextBuilder::build to finalize.

Source

pub fn generate(&self) -> TokenStream

Generates the complete output for this wrapper: an extern "C-unwind" function and an R_CallMethodDef constant, both decorated with #[cfg(...)] attributes if present.

When skip_wrapper is set (for user-written extern "C-unwind" fns), only the R_CallMethodDef is emitted — the fn body itself is already the C symbol.

Dispatches to generate_main_thread_wrapper or generate_worker_thread_wrapper based on thread_strategy.

Source

fn build_c_params(&self) -> (Vec<TokenStream>, Vec<Ident>, Vec<Ident>)

Builds the C wrapper’s parameter list from the Rust function signature.

Returns a tuple of:

  • c_params: SEXP parameter declarations for the C wrapper signature. Always starts with __miniextendr_call (the R call object for error context), followed by self_sexp for instance methods, then arg_0, arg_1, … for each input.
  • rust_args: The original Rust parameter identifiers (used in the call expression).
  • sexp_idents: The generated arg_N identifiers (used in SEXP-to-Rust conversions).
Source

fn build_conversion_stmts(&self, sexp_idents: &[Ident]) -> Vec<TokenStream>

Generates TryFromSexp conversion statements for each parameter.

Each statement converts an arg_N: SEXP into the corresponding Rust type declared in the original function signature. Respects strict and coerce settings.

Used by the main-thread wrapper where all conversions happen inline.

Source

fn build_conversion_stmts_split( &self, sexp_idents: &[Ident], ) -> (Vec<TokenStream>, Vec<TokenStream>)

Build conversion statements split for worker thread execution.

Returns (pre_closure, in_closure) statements:

  • pre_closure: Run on main thread, produce owned values to move
  • in_closure: Run inside worker closure, create borrows
Source

fn generate_main_thread_wrapper(&self) -> TokenStream

Generates an extern "C-unwind" wrapper that runs entirely on the R main thread.

The wrapper body is enclosed in with_r_unwind_protect, which catches both Rust panics and R longjmps and returns a tagged-condition SEXP on failure (the R-side wrapper raises a structured condition). When rng is enabled, the call is additionally wrapped in catch_unwind so that PutRNGstate() runs even on panic.

Source

fn generate_worker_thread_wrapper(&self) -> TokenStream

Generates an extern "C-unwind" wrapper that dispatches to the worker thread.

Structure:

  1. GetRNGstate() (if rng enabled)
  2. catch_unwind around the entire body
  3. Pre-closure conversions on the main thread (produces owned values)
  4. run_on_worker (returns Result<T, String>) with a move closure containing in-closure conversions and the call expression
  5. Return conversion back on the main thread via with_r_unwind_protect
  6. PutRNGstate() (if rng enabled)
  7. Panic handling: either tagged error value or Rf_errorcall
Source

fn generate_return_handling(&self, call_expr: &TokenStream) -> TokenStream

Generates the inline return-handling code for the main-thread wrapper.

Emits the call expression followed by conversion logic based on ReturnHandling. For Option/Result variants, also emits error-path code that returns a tagged condition SEXP (which the R-side wrapper raises).

Source

fn generate_worker_return_handling( &self, call_expr: &TokenStream, ) -> (TokenStream, TokenStream)

Generates return-handling code split between worker and main threads.

Returns (worker_body, return_conversion):

  • worker_body: Runs inside the run_on_worker closure. Contains just the call expression (the worker returns the raw Option/Result for the main thread to inspect).
  • return_conversion: Runs back on the main thread after the worker returns. Converts the Rust value to SEXP (via with_r_unwind_protect). For Option and Result variants, error checking happens here and produces a tagged condition SEXP that the R-side wrapper raises.
Source

fn worker_conversion_unwind_fn(&self) -> TokenStream

Returns the unwind protection function for worker-thread conversion steps. Always returns tagged condition SEXP on conversion panics; the R-side wrapper raises.

Source

fn sexp_conversion_expr(&self, result_ident: &Ident) -> TokenStream

Returns the SEXP conversion expression for result_ident, using strict checked conversion if strict mode is on and the inner return type is lossy, otherwise falling back to IntoR::into_sexp().

Source

fn generate_call_method_def(&self) -> TokenStream

Generates the R_CallMethodDef constant for R’s .Call interface registration.

The constant contains the C symbol name, a DL_FUNC pointer to the wrapper (obtained via transmute), and the argument count. R uses this at package load time (via R_registerRoutines) to register the native routine.

Source

fn generate_doc_comment(&self, thread_info: &str) -> String

Generates a rustdoc comment string for the C wrapper function.

Includes the original function/method name, thread strategy label, and a cross-reference to the R wrapper constant.

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> 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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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