Expand description
§miniextendr-macros - Procedural macros for Rust <-> R interop
This crate provides the procedural macros that power miniextendr’s code
generation. Most users should depend on miniextendr-api and use its
re-exports, but this crate can be used directly when you only need macros.
Primary macros and derives:
#[miniextendr]on functions, impl blocks, trait defs, and trait impls.#[r_ffi_checked]for main-thread routing of C-ABI wrappers.- Derives:
ExternalPtr,RNativeType, ALTREP derives,RFactor. - Helpers:
typed_listfor typed list builders.
R wrapper generation is driven by Rust doc comments (roxygen tags are
extracted). The document binary collects these wrappers and writes
R/miniextendr_wrappers.R during package build.
§Quick start
use miniextendr_api::miniextendr;
#[miniextendr]
fn add(a: i32, b: i32) -> i32 {
a + b
}§Macro expansion pipeline
§Overview
┌──────────────────────────────────────────────────────────────────────────┐
│ #[miniextendr] on fn │
│ │
│ 1. Parse: syn::ItemFn → MiniextendrFunctionParsed │
│ 2. Analyze return type (Result<T>, Option<T>, raw SEXP, etc.) │
│ 3. Generate: │
│ ├── C wrapper: extern "C-unwind" fn C_<name>(call: SEXP, ...) → SEXP │
│ ├── R wrapper: const R_WRAPPER_<NAME>: &str = "..." │
│ └── Registration: const call_method_def_<name>: R_CallMethodDef │
│ 4. Original function preserved (with added attributes) │
└──────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│ #[miniextendr(env|r6|s3|s4|s7)] on impl │
│ │
│ 1. Parse: syn::ItemImpl → extract methods │
│ 2. For each method: │
│ ├── Generate C wrapper (handles self parameter) │
│ ├── Generate R method wrapper string │
│ └── Generate registration entry │
│ 3. Generate class definition code per class system: │
│ ├── env: new.env() + method assignment │
│ ├── r6: R6Class() definition │
│ ├── s3: S3 generics + methods │
│ ├── s4: setClass() + setMethod() │
│ └── s7: new_class() definition │
│ 4. Emit const with combined R code │
└──────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│ #[miniextendr] on trait │
│ │
│ 1. Parse: syn::ItemTrait → extract method signatures │
│ 2. Generate: │
│ ├── Trait tag constant: const TAG_<TRAIT>: mx_tag = ... │
│ ├── Vtable struct: struct __vtable_<Trait> { ... } │
│ └── CCalls table: static MX_CCALL_<TRAIT>: [...] = ... │
│ 3. Original trait preserved │
└──────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────────┐
│ #[miniextendr] impl Trait for Type │
│ │
│ 1. Parse: syn::ItemImpl (trait impl) │
│ 2. Generate: │
│ ├── Vtable instance: static __VTABLE_<TRAIT>_FOR_<TYPE>: ... │
│ ├── Wrapper struct: struct __MxWrapper<Type> { erased, data } │
│ ├── Query function: fn __mx_query_<type>(tag) → vtable ptr │
│ └── Base vtable: static __MX_BASE_VTABLE_<TYPE>: ... │
│ 3. Original impl preserved │
└──────────────────────────────────────────────────────────────────────────┘
§Key Modules
| Module | Purpose |
|---|---|
miniextendr_fn | Function parsing and attribute handling |
c_wrapper_builder | C wrapper generation (extern "C-unwind") |
r_wrapper_builder | R wrapper code generation |
rust_conversion_builder | Rust→SEXP return value conversion |
miniextendr_impl | impl Type block processing |
r_class_formatter | Class system code generation (env/r6/s3/s4/s7) |
miniextendr_trait | Trait ABI metadata generation |
miniextendr_impl_trait | impl Trait for Type vtable generation |
altrep / altrep_derive | ALTREP struct derivation |
externalptr_derive | #[derive(ExternalPtr)] |
roxygen | Roxygen doc comment handling |
§Generated Symbol Naming
For a function my_func:
- C wrapper:
C_my_func - R wrapper const:
R_WRAPPER_MY_FUNC - Registration:
call_method_def_my_func
For a type MyType with trait Counter:
- Vtable:
__VTABLE_COUNTER_FOR_MYTYPE - Wrapper:
__MxWrapperMyType - Query:
__mx_query_mytype
§Return Type Handling
The return_type_analysis module determines how to convert Rust returns to SEXP:
| Rust Type | Strategy | R Result |
|---|---|---|
T: IntoR | .into_sexp() | Converted value |
Result<T, E> | Unwrap or R error | Value or error |
Option<T> | Some → value, None → NULL | Value or NULL |
SEXP | Pass through | Raw SEXP |
() | Invisible NULL | invisible(NULL) |
Use #[miniextendr(unwrap_in_r)] to return Result<T, E> to R without unwrapping.
§Thread Strategy
By default, #[miniextendr] functions run on R’s main thread. Opt into
worker-thread execution with #[miniextendr(worker)] (requires the
worker-thread feature on miniextendr-api). A worker opt-in is ignored
when the signature requires main-thread execution (returns/takes SEXP,
uses variadic dots, or sets check_interrupt).
Note: ExternalPtr<T> is Send — it can be returned from worker
thread functions. All R API operations on ExternalPtr are serialized
through with_r_thread.
§Class Systems
The r_class_formatter module generates R code for different class systems:
| System | Generated R Code | Self Parameter |
|---|---|---|
env | new.env() with methods | self environment |
r6 | R6Class() | self environment |
s3 | structure() + generics | First argument |
s4 | setClass() + setMethod() | First argument |
s7 | new_class() | self property |
Modules§
- altrep 🔒
- ALTREP registration code generation.
- altrep_
derive 🔒 - Derive macros for ALTREP data traits.
- c_
wrapper_ 🔒builder - Unified C wrapper generation for standalone functions and impl methods.
- dataframe_
derive 🔒 - Derive macros for bidirectional row ↔ dataframe conversions.
- externalptr_
derive 🔒 #[derive(ExternalPtr)]- ExternalPtr Support- factor_
derive 🔒 #[derive(RFactor)]- Enum ↔ R Factor Support- lifecycle 🔒
- Lifecycle support for R package deprecation management.
- list_
derive 🔒 - List and Preference Derive Macros
- list_
macro 🔒 - Parser for the
list!macro. - match_
arg_ 🔒derive #[derive(MatchArg)]- Enum ↔ R String withmatch.argSupport- match_
arg_ 🔒keys - Write-time placeholder & symbol-name formatting for the match_arg pipeline.
- method_
return_ 🔒builder - Shared utilities for handling method return values in R wrapper generation.
- miniextendr_
fn 🔒 - Function signature parsing for
#[miniextendr]. - miniextendr_
impl 🔒 - Impl-block Parsing and Wrapper Generation
- miniextendr_
impl_ 🔒trait #[miniextendr]on trait impls - Trait Implementation Registration- miniextendr_
trait 🔒 - Trait Support for
#[miniextendr] - naming 🔒
- Naming helpers for the static symbols the
#[miniextendr]attribute emits. - r_
class_ 🔒formatter - Shared utilities for R class wrapper generation.
- r_
preconditions 🔒 - R-side precondition generation for type checking.
- r_
wrapper_ 🔒builder - Shared utilities for building R wrapper code.
- return_
type_ 🔒analysis - Return type analysis for
#[miniextendr]functions. - roxygen 🔒
- Roxygen tag extraction and processing for R wrapper generation.
- rust_
conversion_ 🔒builder - Shared utilities for converting R SEXP parameters to Rust types.
- struct_
enum_ 🔒dispatch - Dispatch
#[miniextendr]on structs and enums to the appropriate derive helpers. - type_
inspect 🔒 - Lightweight type-introspection helpers shared by parsing and codegen.
- typed_
external_ 🔒macro impl_typed_external!— explicit monomorphization ofTypedExternalfor generic types.- typed_
list 🔒 - Parser for the
typed_list!macro. - util 🔒
- Small cross-cutting helpers used by multiple macro modules.
- vctrs_
generics 🔒 - Known vctrs S3 generic names used to auto-insert
@importFrom vctrs.
Macros§
- __
mx_ 👻trait_ impl_ expand - Internal proc macro used by TPIE (Trait-Provided Impl Expansion).
- impl_
typed_ external - Generate
TypedExternalandIntoExternalPtrimpls for a concrete monomorphization of a generic type. - list
- Construct an R list from Rust values.
- miniextendr_
init - Generate the
R_init_*entry point for a miniextendr R package. - typed_
list - Create a
TypedListSpecfor validating...arguments or lists.
Functions§
- apply_
return_ 🔒pref - Maps a
ReturnPrefattribute value onto an auto-detectedReturnHandling. - build_
match_ 🔒arg_ helpers - Emit the
extern "C-unwind"helper +R_CallMethodDefregistration for each standalone-fnmatch_argparam. - validate_
extern_ 🔒signature - Validate the signature of an
extern "C-unwind"fn exported via#[miniextendr].
Attribute Macros§
- miniextendr
- Export Rust items to R.
- r_
ffi_ checked - Generate thread-safe wrappers for R FFI functions.
Derive Macros§
- Altrep
- Derive ALTREP registration for a data struct.
- Altrep
Complex - Derive macro for ALTREP complex vector data types.
- Altrep
Integer - Derive macro for ALTREP integer vector data types.
- Altrep
List - Derive macro for ALTREP list vector data types.
- Altrep
Logical - Derive macro for ALTREP logical vector data types.
- Altrep
Raw - Derive macro for ALTREP raw vector data types.
- Altrep
Real - Derive macro for ALTREP real vector data types.
- Altrep
String - Derive macro for ALTREP string vector data types.
- Data
Frame Row - Derive
DataFrameRow: generates a companion*DataFrametype with collection fields, plusIntoR/TryFromSexp/IntoDataFrameimpls for seamless R data.frame conversion. - External
Ptr - Derive macro for implementing
TypedExternalon a type. - Into
List - Derive
IntoListfor a struct (Rust → R list). - Match
Arg - Derive
MatchArg: enables conversion between Rust enums and R character strings withmatch.argsemantics (partial matching, informative errors). - Prefer
Data Frame - Derive
PreferDataFrame: when a type implements bothIntoDataFrame(viaDataFrameRow) and other conversion paths, this selects data.frame as the defaultIntoRconversion. - Prefer
External Ptr - Derive
PreferExternalPtr: when a type implements bothExternalPtrand other conversion paths (e.g.,IntoList), this selectsExternalPtrwrapping as the defaultIntoRconversion. - Prefer
List - Derive
PrefersList: when a type implements bothIntoListandExternalPtr, this selects list as the defaultIntoRconversion. - PreferR
Native Type - Derive
PreferRNativeType: when a newtype wraps anRNativeTypeand also implements other conversions, this selects the native R vector conversion as the defaultIntoRpath. - RFactor
- Derive
RFactor: enables conversion between Rust enums and R factors. - RNative
Type - Derive macro for implementing
RNativeTypeon a newtype wrapper. - TryFrom
List - Derive
TryFromListfor a struct (R list → Rust).