3.2 Create a Rust-R Package

3.2.1 Init a Package

rustr_init will create an R package with Rust support.

Just run:

rustr_init("pkgname",".")
#> Creating directories ...
#> Creating DESCRIPTION ...
#> Creating NAMESPACE ...
#> Creating Read-and-delete-me ...
#> Saving functions and data ...
#> Making help files ...
#> Done.
#> Further steps are described in './pkgname/Read-and-delete-me'.
#> added useDynLib to NAMESPACE
#> 
#> It is recommended to change the rustr version in ./src/rustlib/Cargo.toml from "*" to a specific version number to get reproducibility.

list.dirs("pkgname")
#> [1] "pkgname"                 "pkgname/man"            
#> [3] "pkgname/R"               "pkgname/src"            
#> [5] "pkgname/src/rustlib"     "pkgname/src/rustlib/src"

pkgname/src/rustlib is a Rust library, for more info see http://doc.crates.io/

Rust files are in pkgname/src/rustlib/src.

pkgname/src/rustlib/src/lib.rs should begin with:

# Run This In R
headr()
#> #[macro_use]
#> extern crate rustr;
#> pub mod export;
#> pub use rustr::*;
#> 
#> // #[rustr_export]
#> pub fn say_hi()->RResult<String>{
#>    Ok("hello world".into())
#> }

or

#[macro_use]
extern crate rustr;
pub mod export;
pub use rustr::*;

3.2.2 Intro rustrize()

Rust function begin with // #[rustr_export] will be imported to R by rustrize() R function.

// /src/rustlib/src/lib.rs

#[macro_use]
extern crate rustr;
pub mod export;
pub use rustr::*;

// ' Roxygen Comment Header (Optional)
// ' 
// ' detail info about function
// ' @param a parameter detail
// ' @export
// #[rustr_export]
pub fn say_hi()-> String{
    "Hello World!".into()
}

and then run rustrize().

3.2.2.1 Generated Files

These files are generated by rustrize().

  1. /R/REXPORT.R - .Call() binding in R.
  2. /src/REXPORT.c - Exported .Call() Functions.
  3. /src/rustlib/src/export.rs - A public module in /src/rustlib/src/lib.rs, this module export Rust function to R.
# /R/REXPORT.R

#' Roxygen Comment Header (Optional)
#' 
#' detail info about function
#' @param a parameter detail
#' @export
say_hi = function(){ .Call('SvhCRFYxjsuH_say_hi',PACKAGE = 'SvhCRFYxjsuH')}
// /src/REXPORT.c

#include <Rinternals.h>
#include <R.h>

extern SEXP rustr_say_hi();
SEXP SvhCRFYxjsuH_say_hi(){ return(rustr_say_hi());}
// /src/rustlib/src/export.rs

use super::*;

#[no_mangle]
pub extern "C" fn rustr_say_hi()->SEXP{

 let res  = say_hi();

 let res_sexp : SEXP = unwrapr!(res.intor());

 return res_sexp;
}

And your R package are ready to R CMD build.