#[derive(RNativeType)]Expand description
Derive macro for implementing RNativeType on a newtype wrapper.
This gives newtypes native buffer access, borrowed &[T] conversions, and
participation in the Coerce<R> traits. Add #[derive(IntoR)] to return
owned values: T, Vec<T>, Box<[T]>, and their supported nested containers.
RNativeType describes storage; IntoR selects the output representation.
Keeping them separate also permits an ExternalPtr representation.
The inner type must implement RNativeType. Add #[derive(IsNA)]
to forward missing-value detection when the inner type supports NA.
§Supported Struct Forms
Both tuple structs and single-field named structs are supported:
ⓘ
use miniextendr_api::RNativeType;
// Tuple struct (most common)
#[repr(transparent)]
#[derive(Clone, Copy, RNativeType)]
struct UserId(i32);
// Named single-field struct
#[repr(transparent)]
#[derive(Clone, Copy, RNativeType)]
struct Temperature { celsius: f64 }§Generated Code
For struct UserId(i32), this generates:
ⓘ
impl RNativeType for UserId {
const SEXP_TYPE: SEXPTYPE = <i32 as RNativeType>::SEXP_TYPE;
const R_NA: Self = UserId(<i32 as RNativeType>::R_NA);
unsafe fn dataptr_mut(sexp: SEXP) -> *mut Self {
<i32 as RNativeType>::dataptr_mut(sexp).cast()
}
}§Using the Newtype with Coerce
Once RNativeType is derived, you can implement Coerce to/from the newtype:
ⓘ
impl Coerce<UserId> for i32 {
fn coerce(self) -> UserId { UserId(self) }
}
let id: UserId = 42.coerce();§Requirements
- Must be a newtype struct (exactly one field, tuple or named)
- Must use
#[repr(transparent)]so native R buffers have the same layout - The inner type must implement
RNativeType(i32,f64,RLogical,u8,Rcomplex) - Must also be
Copy(RNativeType: Copy): deriveClone, Copywith it