pub(crate) fn extendr_impl(
item_impl: ItemImpl,
opts: &ExtendrOptions,
) -> Result<TokenStream>
Expand description
Make inherent implementations available to R
The extendr_impl
function is used to make inherent implementations
available to R as an environment. By adding the [macro@extendr
] attribute
macro to an impl
block (supported with enum
s and struct
s), the
methods in the impl block are made available as functions in an
environment.
On the R side, an environment with the same name of the inherent
implementation is created. The environment has functions within it
that correspond to each method in the impl block. Note that in order
for an impl block to be compatible with extendr (and thus R), its return
type must be able to be returned to R. For example, any struct that might
be returned must also have an #[extendr]
annotated impl block.
Example:
use extendr_api::prelude::*;
// a struct that will be used internal the People struct
#[derive(Clone, Debug, IntoDataFrameRow)]
struct Person {
name: String,
age: i32,
}
// This will collect people in the struct
#[extendr]
#[derive(Clone, Debug)]
struct People(Vec<Person>);
#[extendr]
/// @export
impl People {
// instantiate a new struct with an empty vector
fn new() -> Self {
let vec: Vec<Person> = Vec::new();
Self(vec)
}
// add a person to the internal vector
fn add_person(&mut self, name: &str, age: i32) -> &mut Self {
let person = Person {
name: String::from(name),
age: age,
};
self.0.push(person);
// return self
self
}
// Convert the struct into a data.frame
fn into_df(&self) -> Robj {
let df = self.0.clone().into_dataframe();
match df {
Ok(df) => df.as_robj().clone(),
Err(_) => data_frame!(),
}
}
// add another `People` struct to self
fn add_people(&mut self, others: &People) -> &mut Self {
self.0.extend(others.0.clone().into_iter());
self
}
// create a function to print the self which can be called
// from an R print method
fn print_self(&self) -> String {
format!("{:?}", self.0)
}
}
// Macro to generate exports.
// This ensures exported functions are registered with R.
// See corresponding C code in `entrypoint.c`.
extendr_module! {
mod testself;
impl People;
}