| Title: | Call Rust Code from R using the 'extendr' Crate |
| Version: | 0.4.2 |
| Description: | Provides functions to compile and load Rust code from R, similar to how 'Rcpp' or 'cpp11' allow easy interfacing with C++ code. Also provides helper functions to create R packages that use Rust code. Under the hood, the Rust crate 'extendr' is used to do all the heavy lifting. |
| License: | MIT + file LICENSE |
| URL: | https://extendr.rs/rextendr/,https://github.com/extendr/rextendr |
| BugReports: | https://github.com/extendr/rextendr/issues |
| Depends: | R (≥ 4.1) |
| Imports: | brio, callr, cli, desc, dplyr, glue (≥ 1.7.0), jsonlite,pkgbuild (≥ 1.4.0), processx, rlang (≥ 1.0.5), rprojroot,stringi, vctrs, withr |
| Suggests: | devtools, rcmdcheck, knitr, lintr, rmarkdown, testthat (≥3.1.7), usethis |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| Config/testthat/parallel: | true |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.2 |
| SystemRequirements: | Rust 'cargo'; the crate 'libR-sys' must compilewithout error |
| NeedsCompilation: | no |
| Packaged: | 2025-08-26 13:21:13 UTC; iliak |
| Author: | Claus O. Wilke |
| Maintainer: | Ilia Kosenkov <ilia.kosenkov@outlook.com> |
| Repository: | CRAN |
| Date/Publication: | 2025-08-26 14:00:02 UTC |
Call Rust code from R using the 'extendr' Crate
Description
The rextendr package implements functions to interface with Rust code from R.Seerust_source() for details.
Author(s)
Maintainer: Ilia Kosenkovilia.kosenkov@outlook.com (ORCID)
Authors:
Claus O. Wilkewilke@austin.utexas.edu (ORCID)
Andy Thomasonandy@andythomason.com
Mossa M. Reimertmossa@sund.ku.dk
Malcolm Barrettmalcolmbarrett@gmail.com (ORCID)
Other contributors:
Josiah Parryjosiah.parry@gmail.con (ORCID) [contributor]
Kenneth Vernonkenneth.b.vernon@gmail.com (ORCID) [contributor]
Alberson Mirandaalbersonmiranda@hotmail.com (ORCID) [contributor]
See Also
Useful links:
Report bugs athttps://github.com/extendr/rextendr/issues
Clean Rust binaries and package cache.
Description
Removes Rust binaries (such as.dll/.so libraries), C wrapper object files,invokescargo clean to reset cargo target directory(found by default atpkg_root/src/rust/target/).Useful when Rust code should be recompiled from scratch.
Usage
clean(path = ".", echo = TRUE)Arguments
path | character scalar, path to R package root. |
echo | logical scalar, should cargo command and outputs be printed toconsole (default is |
Value
character vector with names of all deleted files (invisibly).
Examples
## Not run: clean()## End(Not run)CRAN compliant extendr packages
Description
R packages developed using extendr are not immediately ready tobe published to CRAN. The extendr package template ensures thatCRAN publication is (farily) painless.
CRAN requirements
In order to publish a Rust based package on CRAN it must meet certainrequirements. These are:
Rust dependencies are vendored
The package is compiled offline
the
DESCRIPTIONfile'sSystemRequirementsfield containsCargo (Rust's package manager), rustc
The extendr templates handle all of thisexcept vendoring dependencies.This must be done prior to publication usingvendor_pkgs().
In addition, it is important to make sure that CRAN maintainersare aware that the package they are checking contains Rust code.Depending on which and how many crates are used as a dependenciesthevendor.tar.xz will be larger than a few megabytes. If abuilt package is larger than 5mbs CRAN may reject the submission.
To prevent rejection make a note in yourcran-comments.md file(create one usingusethis::use_cran_comments()) along the lines of"The package tarball is 6mb because Rust dependencies are vendored within src/rust/vendor.tar.xz which is 5.9mb."
Compile Rust code and generate package documentation.
Description
The functionrextendr::document() updates the package documentation for anR package that usesextendr code, taking into account any changes that weremade in the Rust code. It is a wrapper fordevtools::document(), and itexecutesextendr-specific routines before callingdevtools::document().Specifically, it ensures that Rust code is recompiled (when necessary) and thatup-to-date R wrappers are generated before regenerating the package documentation.
Usage
document(pkg = ".", quiet = FALSE, roclets = NULL)Arguments
pkg | The package to use, can be a file path to the package or apackage object. See |
quiet | if |
roclets | Character vector of roclet names to use with package.The default, |
Value
No return value, called for side effects.
Knitr engines
Description
Two knitr engines that enable code chunks of typeextendr (individual Ruststatements to be evaluated viarust_eval()) andextendrsrc (Rust functionsor classes that will be exported to R viarust_source()).
Usage
eng_extendr(options)eng_extendrsrc(options)Arguments
options | A list of chunk options. |
Value
A character string representing the engine output.
Inform the user that a development version ofextendr is being used.
Description
This function returns a string that should be used inside of acli function.Seevalidate_extendr_features() for an example.
Usage
inf_dev_extendr_used()Silence{cli} output
Description
Use for functions that use cli output that should optionally be suppressed.
Usage
local_quiet_cli(quiet, env = rlang::caller_env())Examples
if (interactive()) { hello_rust <- function(..., quiet = FALSE) { local_quiet_cli(quiet) cli::cli_alert_info("This should be silenced when {.code quiet = TRUE}") } hello_rust() hello_rust(quiet = TRUE)}Generate extendr module macro for Rust source
Description
Read some Rust source code, find functions or implementations with the#[extendr] attribute, and generate anextendr_module! macro statement.
Usage
make_module_macro(code, module_name = "rextendr")Arguments
code | Character vector containing Rust code. |
module_name | Module name |
Details
This function uses simple regular expressions to do the Rust parsing andcan get confused by valid Rust code. It is only meant as a convenience forsimple use cases. In particular, it cannot currently handle implementationsfor generics.
Value
Character vector holding the contents of the generated macro statement.
Retrieve metadata for packages and workspaces
Description
Retrieve metadata for packages and workspaces
Usage
read_cargo_metadata(path = ".", dependencies = FALSE, echo = FALSE)Arguments
path | character scalar, the R package directory |
dependencies | Default |
echo | Default |
Details
For more details, seeCargo docsforcargo-metadata. See especially "JSON Format" to get a sense of what youcan expect to find in the returned list.
Value
Alist including the following elements:
packagesworkspace_membersworkspace_default_membersresolvetarget_directoryversionworkspace_rootmetadata
Examples
## Not run: read_cargo_metadata()## End(Not run)Register the extendr module of a package with R
Description
This function generates wrapper code corresponding to the extendr modulefor an R package. This is useful in package development, where we generallywant appropriate R code wrapping the Rust functions implemented via extendr.In most development settings, you will not want to call this function directly,but instead callrextendr::document().
Usage
register_extendr(path = ".", quiet = FALSE, force = FALSE, compile = NA)Arguments
path | Path from which package root is looked up. |
quiet | Logical indicating whether any progress messages should begenerated or not. |
force | Logical indicating whether to force regenerating |
compile | Logical indicating whether to recompile DLLs:
|
Details
The functionregister_extendr() compiles the package Rust code ifrequired, and then the wrapper code is retrieved from the compiledRust code and saved intoR/extendr-wrappers.R. Afterwards, you will haveto re-document and then re-install the package for the wrapper functions totake effect.
Value
(Invisibly) Path to the file containing generated wrappers.
See Also
Evaluate Rust code
Description
Compile and evaluate one or more Rust expressions. If the lastexpression in the Rust code returns a value (i.e., does not end with;), then this value is returned to R. The value returned does not needto be of typeRobj, as long as it can be cast into this type with.into(). This conversion is done automatically, so you don't have toworry about it in your code.
Usage
rust_eval(code, env = parent.frame(), ...)Arguments
code | Input rust code. |
env | The R environment in which the Rust code will be evaluated. |
... | Other parameters handed off to |
Value
The return value generated by the Rust code.
Examples
## Not run: # Rust code without return value, called only for its side effectsrust_eval( code = 'rprintln!("hello from Rust!");')# Rust code with return valuerust_eval( code = " let x = 5; let y = 7; let z = x * y; z // return to R; rust_eval() takes care of type conversion code ")## End(Not run)Report on Rust infrastructure
Description
Prints out a detailed report on the state of Rust infrastructure on the host machine.
Usage
rust_sitrep()Value
Nothing
Compile Rust code and call from R
Description
rust_source() compiles and loads a single Rust file for use in R.rust_function()compiles and loads a single Rust function for use in R.
Usage
rust_source( file, code = NULL, module_name = "rextendr", dependencies = NULL, patch.crates_io = getOption("rextendr.patch.crates_io"), profile = c("dev", "release", "perf"), toolchain = getOption("rextendr.toolchain"), extendr_deps = NULL, features = NULL, env = parent.frame(), use_extendr_api = TRUE, generate_module_macro = TRUE, cache_build = TRUE, quiet = FALSE, use_rtools = TRUE, use_dev_extendr = FALSE)rust_function( code, extendr_fn_options = NULL, env = parent.frame(), quiet = FALSE, use_dev_extendr = FALSE, ...)Arguments
file | Input rust file to source. |
code | Input rust code, to be used instead of |
module_name | Name of the module defined in the Rust source via |
dependencies | Character vector of dependencies lines to be added to the |
patch.crates_io | Character vector of patch statements for crates.io tobe added to the |
profile | Rust profile. Can be either |
toolchain | Rust toolchain. The default, |
extendr_deps | Versions of |
features | A vector of |
env | The R environment in which the wrapping functions will be defined. |
use_extendr_api | Logical indicating whether |
generate_module_macro | Logical indicating whether the Rust modulemacro should be automatically generated from the code. Default is |
cache_build | Logical indicating whether builds should be cached betweencalls to |
quiet | Logical indicating whether compile output should be generated or not. |
use_rtools | Logical indicating whether to append the path to Rtoolsto the |
use_dev_extendr | Logical indicating whether to use development version of |
extendr_fn_options | A list of extendr function options that are inserted into |
... | Other parameters handed off to |
Value
The result fromdyn.load(), which is an object of classDLLInfo.SeegetLoadedDLLs() for more details.
Examples
## Not run: # creating a single rust functionrust_function("fn add(a:f64, b:f64) -> f64 { a + b }")add(2.5, 4.7)# creating multiple rust functions at oncecode <- r"(#[extendr]fn hello() -> &'static str { "Hello, world!"}#[extendr]fn test( a: &str, b: i64) { rprintln!("Data sent to Rust: {}, {}", a, b);})"rust_source(code = code)hello()test("a string", 42)# use case with an external dependency: a function that converts# markdown text to html, using the `pulldown_cmark` crate.code <- r"( use pulldown_cmark::{Parser, Options, html}; #[extendr] fn md_to_html(input: &str) -> String { let mut options = Options::empty(); options.insert(Options::ENABLE_TABLES); let parser = Parser::new_ext(input, options); let mut output = String::new(); html::push_html(&mut output, parser); output })"rust_source( code = code, dependencies = list(`pulldown-cmark` = "0.8"))md_text <- "# The story of the foxThe quick brown fox **jumps over** the lazy dog.The quick *brown fox* jumps over the lazy dog."md_to_html(md_text)## End(Not run)Convert Rlist() into toml-compatible format.
Description
to_toml() can be used to buildCargo.toml.The cargo manifest can be represented in terms ofR objects, allowing limited validation and syntax verification.This function converts manifests written using R objects intotoml representation, applying basic formatting,which is ideal for generating cargomanifests at runtime.
Usage
to_toml(..., .str_as_literal = TRUE, .format_int = "%d", .format_dbl = "%g")Arguments
... | A list from which toml is constructed.Supports nesting and tidy evaluation. |
.str_as_literal | Logical indicating whether to treatstrings as literal (single quotes no escapes) orbasic (escaping some sequences) ones. Default is |
.format_int,.format_dbl | Character scalar describingnumber formatting. Compatible with |
Value
A character vector, each element corresponds toone line of the resulting output.
Examples
# Produces [workspace] with no childrento_toml(workspace = NULL)to_toml(patch.crates_io = list(`extendr-api` = list(git = "git-ref")))# Single-element arrays are distinguished from scalars# using explicitly set `dim`to_toml(lib = list(`crate-type` = array("cdylib", 1)))Add dependencies to a Cargo.toml manifest file
Description
Analogous tousethis::use_package() but for crate dependencies.
Usage
use_crate( crate, features = NULL, git = NULL, version = NULL, optional = FALSE, path = ".", echo = TRUE)Arguments
crate | character scalar, the name of the crate to add |
features | character vector, a list of features to include from thecrate |
git | character scalar, the full URL of the remote Git repository |
version | character scalar, the version of the crate to add |
optional | boolean scalar, whether to mark the dependency as optional(FALSE by default) |
path | character scalar, the package directory |
echo | logical scalar, should cargo command and outputs be printed toconsole (default is TRUE) |
Details
For more details regarding these and other options, see theCargo docsforcargo-add.
Value
NULL (invisibly)
Examples
## Not run: # add to [dependencies]use_crate("serde")# add to [dependencies] and [features]use_crate("serde", features = "derive")# add to [dependencies] using github repository as sourceuse_crate("serde", git = "https://github.com/serde-rs/serde")# add to [dependencies] with specific versionuse_crate("serde", version = "1.0.1")# add to [dependencies] with optional compilationuse_crate("serde", optional = TRUE)## End(Not run)Set up a package for use with Rust extendr code
Description
Create the scaffolding needed to add Rust extendr code to an R package.use_extendr()adds a small Rust library with a single Rust function that returns the string"Hello world!". It also adds wrapper code so this Rust function can be called fromR withhello_world().
Usage
use_extendr( path = ".", crate_name = NULL, lib_name = NULL, quiet = FALSE, overwrite = NULL, edition = c("2021", "2018"))Arguments
path | File path to the package for which to generate wrapper code. |
crate_name | String that is used as the name of the Rust crate.If |
lib_name | String that is used as the name of the Rust library.If |
quiet | Logical indicating whether any progress messages should begenerated or not. |
overwrite | Logical scalar or |
edition | String indicating which Rust edition is used; Default |
Value
A logical value (invisible) indicating whether any package files weregenerated or not.
extendr README badge
Description
Add the version of extendr being used by an R package to its README.
Usage
use_extendr_badge(path = ".")Arguments
path | File path to the package for which to generate wrapper code. |
Details
Requiresusethis to be available.
Examples
## Not run: use_extendr_badge()## End(Not run)Set the minimum supported rust version (MSRV)
Description
use_msrv() sets the minimum supported rust version for your R package.
Usage
use_msrv(version, path = ".", overwrite = FALSE)Arguments
version | character scalar, the minimum supported Rust version. |
path | character scalar, path to folder containing DESCRIPTION file. |
overwrite | default |
Details
The minimum supported rust version (MSRV) is determined by theSystemRequirements field in a package'sDESCRIPTION file. For example, toset the MSRV to1.67.0, theSystemRequirements must haverustc >= 1.67.0.
By default, there is no MSRV set. However, some crates have features thatdepend on a minimum version of Rust. As of this writing the version of Ruston CRAN's Fedora machine's is 1.69. If you require a version of Rust that isgreater than that, you must set it in your DESCRIPTION file.
It is also important to note that if CRAN's machines do not meet thespecified MSRV, they will not be able to build a binary of your package. As aconsequence, if users try to install the package they will be required tohave Rust installed as well.
To determine the MSRV of your R package, we recommend installing thecargo-msrv cli. You can do so by runningcargo install cargo-msrv. Todetermine your MSRV, set your working directory tosrc/rust then runcargo msrv. Note that this may take a while.
For more details, please seecargo-msrv.
Value
version
Examples
## Not run: use_msrv("1.67.1")## End(Not run)Set up VS Code configuration for an rextendr project
Description
This creates a.vscode folder (if needed) and populates it with asettings.json template. If already exists, it will be updated to includetherust-analyzer.linkedProjects setting.
Usage
use_vscode(quiet = FALSE, overwrite = NULL)use_positron(quiet = FALSE, overwrite = NULL)Arguments
quiet | If |
overwrite | If |
Details
Rust-Analyzer VSCode extension looks for aCargo.toml file in theworkspace root by default. This function creates a.vscode folder andpopulates it with asettings.json file that sets the workspace root tothesrc directory of the package. This allows you to open the packagedirectory in VSCode and have the Rust-Analyzer extension work correctly.
Value
TRUE (invisibly) if the settings file was created or updated.
Vendor Rust dependencies
Description
vendor_pkgs() is used to package the dependencies as required by CRAN.It executescargo vendor on your behalf creating avendor/ directory and acompressedvendor.tar.xz which will be shipped with package itself.If you have modified your dependencies, you will need need to repackage
Usage
vendor_pkgs(path = ".", quiet = FALSE, overwrite = NULL)Arguments
path | File path to the package for which to generate wrapper code. |
quiet | Logical indicating whether any progress messages should begenerated or not. |
overwrite | Logical scalar or |
Value
vendor_pkgs()returns a data.frame with two columnscrateandversion
Examples
## Not run: vendor_pkgs()## End(Not run)Generate LICENSE.note file.
Description
LICENSE.note generated by this function contains information about allrecursive dependencies in Rust crate.
Usage
write_license_note(path = ".", quiet = FALSE, force = TRUE)Arguments
path | character scalar, the R package directory |
quiet | logical scalar, whether to signal successful writing ofLICENSE.note (default is |
force | logical scalar, whether to regenerate LICENSE.note ifLICENSE.note already exists (default is |
Value
text printed to LICENSE.note (invisibly).
Examples
## Not run: write_license_note()## End(Not run)