pub trait TraitView: Sized {
const TAG: mx_tag;
// Required method
unsafe fn from_raw_parts(
data: *mut c_void,
vtable: *const c_void,
owner: Option<SEXP>,
) -> Self;
// Provided methods
unsafe fn try_from_sexp(sexp: SEXP) -> Option<Self> { ... }
unsafe fn try_from_sexp_or_error(
sexp: SEXP,
trait_name: &str,
) -> Result<Self, String> { ... }
}Expand description
Trait for view types that can be created from SEXP via trait dispatch.
This trait is implemented by the macro-generated <Trait>View structs.
It provides a common interface for:
- Querying whether an object implements a trait
- Creating a view from an SEXP
§Generated by #[miniextendr] on traits
When you write:
#[miniextendr]
pub trait Counter {
fn value(&self) -> i32;
fn increment(&mut self);
}The generated view keeps its pointers in TraitViewData. Views made
from an R external pointer root that owner until they are dropped;
raw Rust-owned views instead require the caller to keep their data alive.
§Usage
// Try to get a Counter view from an R object
let view = CounterView::try_from_sexp(obj)?;
// Call methods through the view
view.increment();
let val = view.value();§Safety
The from_raw_parts method is unsafe because:
datamust be a valid pointer to theRefCellholding the concrete object (the vtable’s shims borrow it for each call)vtablemust be a valid pointer to the trait’s vtable- The vtable must remain valid for the lifetime of the view
- The owner, when supplied, must keep
dataalive; otherwise the caller must keepdataalive for the lifetime of the view
Required Associated Constants§
Required Methods§
Sourceunsafe fn from_raw_parts(
data: *mut c_void,
vtable: *const c_void,
owner: Option<SEXP>,
) -> Self
unsafe fn from_raw_parts( data: *mut c_void, vtable: *const c_void, owner: Option<SEXP>, ) -> Self
Create a view from raw data and vtable pointers.
§Safety
datamust be a valid, non-null pointer to theRefCellholding the concrete objectvtablemust be a valid, non-null pointer to the trait’s vtablevtablemust remain valid for the lifetime of the viewowner, when present, must be a live R object owningdata; the implementation must root it for the lifetime of the view- Without an owner, the caller must keep
dataalive for that lifetime - A call that conflicts with one still running on the same object raises
the
miniextendr_borrow_conflicterror (the shims borrow itsRefCell) - Construction, use and drop must all run on R’s main thread
Provided Methods§
Sourceunsafe fn try_from_sexp(sexp: SEXP) -> Option<Self>
unsafe fn try_from_sexp(sexp: SEXP) -> Option<Self>
Try to create a view from an R SEXP.
Queries the object for this trait’s vtable using mx_query. If the
object implements the trait, returns Some(view). Otherwise returns None.
§Safety
sexpmust be a valid R external pointer (EXTPTRSXP)- The object must stay live through construction; the view then roots it
- A call that conflicts with one still running on the same object raises
the
miniextendr_borrow_conflicterror (the shims borrow itsRefCell) - Construction, use and drop must all run on R’s main thread
§Returns
Some(Self)if the object implements the traitNoneif the object does not implement the trait
§Example
let counter = unsafe { CounterView::try_from_sexp(obj) }
.expect("Object does not implement Counter");Sourceunsafe fn try_from_sexp_or_error(
sexp: SEXP,
trait_name: &str,
) -> Result<Self, String>
unsafe fn try_from_sexp_or_error( sexp: SEXP, trait_name: &str, ) -> Result<Self, String>
Try to create a view, returning an error message on failure.
Similar to try_from_sexp but returns an error string suitable for
use as an R error message if the object does not implement the trait.
§Safety
Same as try_from_sexp.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".