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: IdentIdentifier of the original Rust function or method being wrapped.
c_ident: IdentIdentifier for the generated C wrapper (e.g., C_foo or C_Type__method).
r_wrapper_const: IdentIdentifier 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: ReturnTypeThe 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: TokenStreamThe actual Rust call expression (e.g., my_func(arg0, arg1) or
self_ref.method(arg0)). Inserted into the wrapper body after conversions.
thread_strategy: ThreadStrategyWhether to run on the main R thread or dispatch to the worker thread.
return_handling: ReturnHandlingHow to convert the Rust return value into a SEXP for R.
coerce_all: boolWhen 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: boolWhen true, emits R_CheckUserInterrupt() before the call expression.
Set by #[miniextendr(check_interrupt)].
rng: boolWhen 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: boolWhether 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: boolWhen 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 VecMatchArg::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: boolWhen 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: VisibilityVisibility 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: GenericsGeneric parameters of the wrapped function, emitted on the C wrapper signature
as fn #c_ident #generics(...). Default: empty (no generics).
skip_wrapper: boolWhen 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
impl CWrapperContext
Sourcepub fn builder(fn_ident: Ident, c_ident: Ident) -> CWrapperContextBuilder
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.
Sourcepub fn generate(&self) -> TokenStream
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.
Sourcefn build_c_params(&self) -> (Vec<TokenStream>, Vec<Ident>, Vec<Ident>)
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:SEXPparameter declarations for the C wrapper signature. Always starts with__miniextendr_call(the R call object for error context), followed byself_sexpfor instance methods, thenarg_0,arg_1, … for each input.rust_args: The original Rust parameter identifiers (used in the call expression).sexp_idents: The generatedarg_Nidentifiers (used in SEXP-to-Rust conversions).
Sourcefn build_conversion_stmts(&self, sexp_idents: &[Ident]) -> Vec<TokenStream>
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.
Sourcefn build_conversion_stmts_split(
&self,
sexp_idents: &[Ident],
) -> (Vec<TokenStream>, Vec<TokenStream>)
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
Sourcefn generate_main_thread_wrapper(&self) -> TokenStream
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.
Sourcefn generate_worker_thread_wrapper(&self) -> TokenStream
fn generate_worker_thread_wrapper(&self) -> TokenStream
Generates an extern "C-unwind" wrapper that dispatches to the worker thread.
Structure:
GetRNGstate()(ifrngenabled)catch_unwindaround the entire body- Pre-closure conversions on the main thread (produces owned values)
run_on_worker(returnsResult<T, String>) with amoveclosure containing in-closure conversions and the call expression- Return conversion back on the main thread via
with_r_unwind_protect PutRNGstate()(ifrngenabled)- Panic handling: either tagged error value or
Rf_errorcall
Sourcefn generate_return_handling(&self, call_expr: &TokenStream) -> TokenStream
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).
Sourcefn generate_worker_return_handling(
&self,
call_expr: &TokenStream,
) -> (TokenStream, TokenStream)
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 therun_on_workerclosure. Contains just the call expression (the worker returns the rawOption/Resultfor the main thread to inspect).return_conversion: Runs back on the main thread after the worker returns. Converts the Rust value to SEXP (viawith_r_unwind_protect). ForOptionandResultvariants, error checking happens here and produces a tagged condition SEXP that the R-side wrapper raises.
Sourcefn worker_conversion_unwind_fn(&self) -> TokenStream
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.
Sourcefn sexp_conversion_expr(&self, result_ident: &Ident) -> TokenStream
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().
Sourcefn generate_call_method_def(&self) -> TokenStream
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.
Sourcefn generate_doc_comment(&self, thread_info: &str) -> String
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§
impl Freeze for CWrapperContext
impl RefUnwindSafe for CWrapperContext
impl !Send for CWrapperContext
impl !Sync for CWrapperContext
impl Unpin for CWrapperContext
impl UnsafeUnpin for CWrapperContext
impl UnwindSafe for CWrapperContext
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> SizedTypeProperties for T
impl<T> SizedTypeProperties for T
Source§#[doc(hidden)]const SIZE: usize = _
#[doc(hidden)]const SIZE: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGN: usize = _
#[doc(hidden)]const ALIGN: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGNMENT: Alignment = _
#[doc(hidden)]const ALIGNMENT: Alignment = _
ptr_alignment_type)Source§#[doc(hidden)]const IS_ZST: bool = _
#[doc(hidden)]const IS_ZST: bool = _
sized_type_properties)Source§#[doc(hidden)]const LAYOUT: Layout = _
#[doc(hidden)]const LAYOUT: Layout = _
sized_type_properties)Source§#[doc(hidden)]const MAX_SLICE_LEN: usize = _
#[doc(hidden)]const MAX_SLICE_LEN: usize = _
sized_type_properties)[Self]. Read moreLayout§
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