diff --git a/dev/news/index.html b/dev/news/index.html index 3705d7aa..f124ec68 100644 --- a/dev/news/index.html +++ b/dev/news/index.html @@ -59,6 +59,7 @@

#321)
  • Support RTOOLS44 (#347)
  • Removed use_try_from as an option in rust_function, and added use_rng (#354)
  • +
  • Added use_crate() function to make adding dependencies to Cargo.toml easier within R, similar to usethis::use_package() (#361)
  • rextendr 0.3.0

    CRAN release: 2023-05-30

    diff --git a/dev/pkgdown.yml b/dev/pkgdown.yml index 41ff0b1d..abfaa064 100644 --- a/dev/pkgdown.yml +++ b/dev/pkgdown.yml @@ -6,4 +6,4 @@ articles: package: package.html rmarkdown: rmarkdown.html setting_up_rust: setting_up_rust.html -last_built: 2024-08-03T16:04Z +last_built: 2024-08-03T19:49Z diff --git a/dev/search.json b/dev/search.json index 0b4ff370..f6e6631f 100644 --- a/dev/search.json +++ b/dev/search.json @@ -1 +1 @@ -[{"path":[]},{"path":"/dev/CODE-OF-CONDUCT.html","id":"our-pledge","dir":"","previous_headings":"","what":"Our Pledge","title":"Contributor Covenant Code of Conduct","text":"contributors maintainers project, pledge make participation community harassment-free experience everyone, regardless age, body size, visible invisible disability, ethnicity, sex characteristics, gender identity expression, level experience, education, socio-economic status, nationality, personal appearance, race, religion, sexual identity orientation. pledge act interact ways contribute open, welcoming, diverse, inclusive, healthy community.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"our-standards","dir":"","previous_headings":"","what":"Our Standards","title":"Contributor Covenant Code of Conduct","text":"Examples behavior contributes positive environment community include: Demonstrating empathy kindness toward people respectful differing opinions, viewpoints, experiences Giving gracefully accepting constructive feedback Accepting responsibility apologizing affected mistakes, learning experience Focusing best just us individuals, overall community Examples unacceptable behavior include: use sexualized language imagery, sexual attention advances kind Trolling, insulting derogatory comments, personal political attacks Public private harassment Publishing others’ private information, physical email address, without explicit permission conduct reasonably considered inappropriate professional setting","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"enforcement-responsibilities","dir":"","previous_headings":"","what":"Enforcement Responsibilities","title":"Contributor Covenant Code of Conduct","text":"Project leaders responsible clarifying enforcing standards acceptable behavior take appropriate fair corrective action response behavior deem inappropriate, threatening, offensive, harmful. Project leaders right responsibility remove, edit, reject comments, commits, code, wiki edits, issues, contributions aligned Code Conduct, communicate reasons moderation decisions appropriate.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"scope","dir":"","previous_headings":"","what":"Scope","title":"Contributor Covenant Code of Conduct","text":"Code Conduct applies within community spaces, also applies individual officially representing community public spaces. Examples representing community include using official e-mail address, posting via official social media account, acting appointed representative online offline event.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"enforcement","dir":"","previous_headings":"","what":"Enforcement","title":"Contributor Covenant Code of Conduct","text":"Instances abusive, harassing, otherwise unacceptable behavior may reported current maintainers project via email. Maintainers email addresses provided DESCRIPTION file. complaints reviewed investigated promptly fairly. community leaders obligated respect privacy security reporter incident.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"enforcement-guidelines","dir":"","previous_headings":"","what":"Enforcement Guidelines","title":"Contributor Covenant Code of Conduct","text":"Community leaders follow Community Impact Guidelines determining consequences action deem violation Code Conduct:","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"id_1-correction","dir":"","previous_headings":"Enforcement Guidelines","what":"1. Correction","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Use inappropriate language behavior deemed unprofessional unwelcome community. Consequence: private, written warning community leaders, providing clarity around nature violation explanation behavior inappropriate. public apology may requested.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"id_2-warning","dir":"","previous_headings":"Enforcement Guidelines","what":"2. Warning","title":"Contributor Covenant Code of Conduct","text":"Community Impact: violation single incident series actions. Consequence: warning consequences continued behavior. interaction people involved, including unsolicited interaction enforcing Code Conduct, specified period time. includes avoiding interactions community spaces well external channels like social media. Violating terms may lead temporary permanent ban.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"id_3-temporary-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"3. Temporary Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: serious violation community standards, including sustained inappropriate behavior. Consequence: temporary ban sort interaction public communication community specified period time. public private interaction people involved, including unsolicited interaction enforcing Code Conduct, allowed period. Violating terms may lead permanent ban.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"id_4-permanent-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"4. Permanent Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Demonstrating pattern violation community standards, including sustained inappropriate behavior, harassment individual, aggression toward disparagement classes individuals. Consequence: permanent ban sort public interaction within community.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributor Covenant Code of Conduct","text":"Code Conduct adapted Contributor Covenant, version 2.0, available https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. Community Impact Guidelines inspired Mozilla’s code conduct enforcement ladder. answers common questions code conduct, see FAQ https://www.contributor-covenant.org/faq. Translations available https://www.contributor-covenant.org/translations.","code":""},{"path":"/dev/CONTRIBUTING.html","id":null,"dir":"","previous_headings":"","what":"Contributing","title":"Contributing","text":"welcome contributions rextendr project. Contributions come many forms. Please carefully read follow guidelines. help us make contribution process easy effective everyone involved. also communicates agree respect time developers managing developing project.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"quicklinks","dir":"","previous_headings":"","what":"Quicklinks","title":"Contributing","text":"Code Conduct Issues Pull Requests Code Style Getting Help Authorship Attribution","code":""},{"path":"/dev/CONTRIBUTING.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of Conduct","title":"Contributing","text":"take open source community seriously hold contributors high standards communication. participating contributing project, agree uphold Code Conduct.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"getting-started","dir":"","previous_headings":"","what":"Getting Started","title":"Contributing","text":"Contributions can made via Issues Pull Requests (PRs). general guidelines cover : Please search existing Issues PRs creating . work hard makes sure issues handled timely manner , depending problem maintainer availability, take investigate problem. friendly ping comment thread can help draw attention issue received attention . Please keep mind contributors project volunteers may commitments need attend .","code":""},{"path":"/dev/CONTRIBUTING.html","id":"issues","dir":"","previous_headings":"Getting Started","what":"Issues","title":"Contributing","text":"Issues used report problems library, request new feature, discuss potential changes PR created. Please use Issues request user support. Whenever possible, please provide minimal reproducible example (reprex) bug report filing. minimal example, likely somebody else can figure problem , please remove code isn’t relevant problem reporting. Please keep issues focused one particular problem. Don’t feel shy opening multiple issues ’re encountering one problem. find Issue addresses problem ’re , please add reproduction information existing issue rather creating new one. Adding reaction can also help indicating maintainers particular problem affecting just reporter.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"pull-requests","dir":"","previous_headings":"Getting Started","what":"Pull Requests","title":"Contributing","text":"PRs always welcome can quick way get fix improvement slated next release. However, please always open Issue submitting PR. general, PRs : Address single concern least number changed lines possible. fix/add functionality question address wide-spread whitespace/style issues, . Add unit integration tests fixed changed functionality. Include documentation. Indicate Issue address using words Closes # Fixes # body PR /git commit message. (See GitHub Documentation details linking PRs Issues automatically closing Issues merging PRs.) general, follow GitHub flow development model: Fork repository Github account Clone project machine Create branch locally succinct descriptive name Commit changes branch Push changes fork Open PR repository follow PR template can efficiently review changes.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"code-style","dir":"","previous_headings":"Getting Started","what":"Code style","title":"Contributing","text":"New code follow tidyverse style guide. can use styler package apply styles, please don’t restyle code nothing PR. use roxygen2, Markdown syntax, documentation. use testthat unit tests. Contributions test cases included easier accept.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"getting-help","dir":"","previous_headings":"","what":"Getting Help","title":"Contributing","text":"Please join us Discord server general conversations questions don’t belong GitHub issue.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"authorship","dir":"","previous_headings":"","what":"Authorship","title":"Contributing","text":"Contributors made multiple, sustained, /non-trivial contributions project may added author list. New author names always added end list, author order reflects chronological order joining project. authorship decisions discretion current maintainers project.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributing","text":"document adapted General Contributing Guidelines auth0 project.","code":""},{"path":"/dev/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"MIT License","title":"MIT License","text":"Copyright (c) 2020 rextendr authors Permission hereby granted, free charge, person obtaining copy software associated documentation files (“Software”), deal Software without restriction, including without limitation rights use, copy, modify, merge, publish, distribute, sublicense, /sell copies Software, permit persons Software furnished , subject following conditions: copyright notice permission notice shall included copies substantial portions Software. SOFTWARE PROVIDED “”, WITHOUT WARRANTY KIND, EXPRESS IMPLIED, INCLUDING LIMITED WARRANTIES MERCHANTABILITY, FITNESS PARTICULAR PURPOSE NONINFRINGEMENT. EVENT SHALL AUTHORS COPYRIGHT HOLDERS LIABLE CLAIM, DAMAGES LIABILITY, WHETHER ACTION CONTRACT, TORT OTHERWISE, ARISING , CONNECTION SOFTWARE USE DEALINGS SOFTWARE.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"systemrequirements","dir":"Articles","previous_headings":"","what":"SystemRequirements","title":"CRAN compliant extendr packages","text":"Building Rust-backed packages source requires system dependencies cargo rustc. CRAN stipulated preferred way tracking using following line packages DESCRIPTION file. Even though free-form field, consistency can help whole ecosystem keep track Rust-based R packages.","code":"SystemRequirements: Cargo (Rust's package manager), rustc"},{"path":"/dev/articles/cran-compliance.html","id":"cargo-and-rustc-availability","dir":"Articles","previous_headings":"","what":"cargo and rustc availability","title":"CRAN compliant extendr packages","text":"order R package built source, cargo rustc need available machine compiling package. expectation R packages using external dependencies configure configure.win files check dependencies available attempting compile package. checks fail, build process stopped prematurely. CRAN expects cargo PATH, user’s home directory checked ~/.cargo/bin. configuration files must perform checks.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"cargo-build-settings","dir":"Articles","previous_headings":"","what":"cargo build settings","title":"CRAN compliant extendr packages","text":"CRAN also imposes restrictions cargo builds crates. CRAN requested two logical CPUs used build process. default, cargo uses multiple threads speed compilation process. CRAN policy allows maximum two. set using -j 2 option, passed cargo build. Additionally, minimize security risks ensure package stability, CRAN requires packages built completely offline. prevents external dependencies downloaded compile time. requirement, vendored dependencies must used.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"vendored-dependencies","dir":"Articles","previous_headings":"","what":"Vendored dependencies","title":"CRAN compliant extendr packages","text":"Vendoring dependencies act including dependency package source code. case Rust, dependencies fetched compile time. enable compilation offline environment, dependencies must vendored, accomplished using cargo vendor command. cargo vendor creates local directory default name vendor, contains source code recursive dependencies crate built. CRAN compatibility, vendor directory must compressed using tar xz compression included source package. build time, dependencies extracted, compiled, discarded. process controlled Makevars Makevars.win files.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"package-compilation","dir":"Articles","previous_headings":"","what":"Package compilation","title":"CRAN compliant extendr packages","text":"comes together package compilation time, providing following requirements met: cargo must able called user’s home directory user’s home directory must modified written package must compiled offline two logical CPUs used versions cargo rustc printed","code":""},{"path":"/dev/articles/cran-compliance.html","id":"using-cran-defaults","dir":"Articles","previous_headings":"","what":"Using CRAN defaults","title":"CRAN compliant extendr packages","text":"rextendr provides default CRAN compliant scaffolding via use_cran_defaults() function appropriate vendoring vendor_pkgs().","code":""},{"path":"/dev/articles/cran-compliance.html","id":"making-a-package-cran-compliant","dir":"Articles","previous_headings":"Using CRAN defaults","what":"Making a package CRAN compliant","title":"CRAN compliant extendr packages","text":"create CRAN compliant R package begin creating new R package. calling usethis::create_package(). new R project, run rextendr::use_extendr() create minimal scaffolding necessary Rust-powered R package. done , can now run rextendr::use_cran_defaults(). use_cran_defaults() create configure configure.win files. Additionally, create new Makevars Makevars.win print versions cargo rustc well use cargo build argument -j 2 --offline.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"vendoring-packages","dir":"Articles","previous_headings":"Using CRAN defaults","what":"Vendoring packages","title":"CRAN compliant extendr packages","text":"configured R package use CRAN defaults, need vendor dependencies. vendor_pkgs() runs cargo vendor behalf, compresses vendor/ directory, updates vendor-config.toml file accordingly. added new dependencies, changed version source crates, use vendor_pkgs() . ensures compressed vendor.tar.xz contains updates . important CI publishing CRAN.","code":""},{"path":"/dev/articles/package.html","id":"create-a-template-package","dir":"Articles","previous_headings":"","what":"Create a template package","title":"Using Rust code in R packages","text":"Creating R package extendr easy rextendr package. First, create empty R package. can usethis::create_package(). Let’s pick myextendr package name. , execute rextendr::use_extendr() inside package directory create scaffolding use extendr. developers use RStudio, also provide project template call usethis::create_package() rextendr::use_extendr() . done using RStudio’s Create Project command, can find global toolbar File menu. Choose “New Directory” select “R package extendr.” can fill details match preferences. project directory setup, strongly encourage run rextendr::rust_sitrep() console. provide detailed report current state Rust infrastructure, along helpful advice address issues may arise. Assuming proper installation Rust, just one step away calling Rust functions R. message says, need run rextendr::document(). , moving forward, let’s look files added.","code":"usethis::create_package(\"path/to/myextendr\") rextendr::use_extendr() #> ✓ Creating src/rust/src. #> ✓ Setting active project to 'path/to/myextendr' #> ✓ Writing 'src/entrypoint.c' #> ✓ Writing 'src/Makevars' #> ✓ Writing 'src/Makevars.win' #> ✓ Writing 'src/.gitignore' #> ✓ Writing src/rust/Cargo.toml. #> ✓ Writing 'src/rust/src/lib.rs' #> ✓ Writing 'R/extendr-wrappers.R' #> ✓ Finished configuring extendr for package myextendr. #> • Please update the system requirement in DESCRIPTION file. #> • Please run `rextendr::document()` for changes to take effect."},{"path":"/dev/articles/package.html","id":"package-structure","dir":"Articles","previous_headings":"","what":"Package structure","title":"Using Rust code in R packages","text":"following files added rextendr::use_extendr(): R/extendr-wrappers.R: file contains auto-generated R functions Rust code. don’t modify file hand. src/Makevars, src/Makevars.win: files hook cargo build installation R package. cases, don’t edit . src/entrypoint.c: file needed avoid linker removing static library. 99.9% cases, don’t edit (except changing crate name). src/rust/: Rust code crate using extendr-api. mainly write code. , short, really look two files:","code":". ├── R │ └── extendr-wrappers.R ... └── src ├── Makevars ├── Makevars.win ├── entrypoint.c └── rust ├── Cargo.toml └── src └── lib.rs"},{"path":"/dev/articles/package.html","id":"srcrustcargo-toml","dir":"Articles","previous_headings":"Package structure","what":"src/rust/Cargo.toml","title":"Using Rust code in R packages","text":"crate name name R package’s name default. can change , might bit cumbersome tweak files accordingly, recommend leaving . probably want specify concrete extendr version, example extendr-api = '0.2'. try development version extendr, can modify last line read","code":"[package] name = 'myextendr' version = '0.1.0' edition = '2021' [lib] crate-type = [ 'staticlib' ] [dependencies] extendr-api = '*' extendr-api = { git = 'https://github.com/extendr/extendr' }"},{"path":"/dev/articles/package.html","id":"srcrustsrclib-rs","dir":"Articles","previous_headings":"Package structure","what":"src/rust/src/lib.rs","title":"Using Rust code in R packages","text":"Let’s explain file line line. first line, containing use statement, declares commonly used extendr API functions Rust compiler. Next, may notice / repeated three times, usual Rust comments require two slashes (.e., //). one Rust’s “doc comment” notation generate crate’s documentation. extendr, lines copied auto-generated R code roxygen comments. analogous Rcpp/cpp11’s //'. next line core extendr’s mechanism. function marked macro, corresponding R function generated automatically. analogous Rcpp’s [[Rcpp::export]] cpp11’s [[cpp11::register]]. last 3 lines macro generating exports, comment explains. implement another function just hello_world, needs listed well marking #[extendr] macro.","code":"use extendr_api::prelude::*; /// Return string `\"Hello world!\"` to R. /// @export #[extendr] fn hello_world() -> &'static str { \"Hello world!\" } // Macro to generate exports. // This ensures exported functions are registered with R. // See corresponding C code in `entrypoint.c`. extendr_module! { mod myextendr; fn hello_world; } use extendr_api::prelude::*; /// Return string `\"Hello world!\"` to R. /// @export #[extendr] // Macro to generate exports. // This ensures exported functions are registered with R. // See corresponding C code in `entrypoint.c`. extendr_module! { mod myextendr; fn hello_world; }"},{"path":[]},{"path":"/dev/articles/package.html","id":"compile","dir":"Articles","previous_headings":"Compile and use the package","what":"Compile","title":"Using Rust code in R packages","text":"Compiling Rust code R functions easy executing one command: might wonder compilation triggered function name just document(). Well, compilation actually needed generate documentation R wrapper code Rust code. consistent behavior devtools::document() packages using C C++. , following files updated generated: src/rust/target/release/libmyextendr.(extension depends OS): static library built Rust code. used compiling shared object myextendr.. src/myextendr.(extension depends OS): shared object actually called R. R/extendr-wrappers.R: auto-generated R functions, including roxygen comments, go file. roxygen comments accordingly converted Rd files NAMESPACE. man/, NAMESPACE: generated roxygen comments.","code":"rextendr::document() #> ✓ Saving changes in the open files. #> ℹ Generating extendr wrapper functions for package: myextendr. #> ! No library found at src/myextendr.so, recompilation is required. #> Re-compiling myextendr #> ─ installing *source* package ‘myextendr’ ... (347ms) #> ** using staged installation #> ** libs #> rm -Rf myextendr.so ./rust/target/release/libmyextendr.a entrypoint.o #> gcc -std=gnu99 -I\"/usr/share/R/include\" -DNDEBUG -fpic -g -O2 -fdebug-prefix-map=/build/r-base-tbZjLv/r-base-4.1.0=. #> -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -UNDEBUG -Wall -pedantic -g -O0 #> -fdiagnostics-color=always -c entrypoint.c -o entrypoint.o #> cargo build --lib --release --manifest-path=./rust/Cargo.toml #> Updating crates.io index #> Compiling proc-macro2 v1.0.27 #> Compiling unicode-xid v0.2.2 #> Compiling libR-sys v0.2.1 #> Compiling syn v1.0.72 #> Compiling extendr-engine v0.2.0 #> Compiling lazy_static v1.4.0 #> Compiling quote v1.0.9 #> Compiling extendr-macros v0.2.0 #> Compiling extendr-api v0.2.0 #> Compiling myextendr v0.1.0 (path/to/myextendr/src/rust) #> Finished release [optimized] target(s) in 19.05s #> gcc -std=gnu99 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o myextendr.so entrypoint.o -L./rust/target/release #> -lmyextendr -L/usr/lib/R/lib -lR #> installing to /tmp/RtmpfMcL08/devtools_install_e2d6351b843c/00LOCK-myextendr/00new/myextendr/libs #> ** checking absolute paths in shared objects and dynamic libraries #> ─ DONE (myextendr) #> ✓ Writing 'R/extendr-wrappers.R'. #> ℹ Updating myextendr documentation #> ℹ Loading myextendr #> Writing NAMESPACE #> Writing NAMESPACE #> Writing hello_world.Rd . ... ├── NAMESPACE ----------(4) ├── R │ └── extendr-wrappers.R ----------(3) ├── man │ └── hello_world.Rd ----------(4) └── src ├── myextendr.so ----------(2) └── rust └── target └── release ├── libmyextendr.a ---(1) ..."},{"path":"/dev/articles/package.html","id":"load-and-use","dir":"Articles","previous_headings":"Compile and use the package","what":"Load and use","title":"Using Rust code in R packages","text":"running rextendr::document(), can just load package devtools::load_all() (alternatively install call library()) call function implemented Rust.","code":"devtools::load_all(\".\") hello_world() #> [1] \"Hello world!\""},{"path":"/dev/articles/package.html","id":"rust-code-vs-generated-r-code","dir":"Articles","previous_headings":"","what":"Rust code vs generated R code","title":"Using Rust code in R packages","text":"never edit R wrapper code hand, might good know R code generated Rust code. Let’s look R/extendr-wrappers.R: , .Call(\"wrap__make_myextendr_wrappers\", use_symbols = ... function call executed rextendr::document(). section @docType package needed generate useDynLib(myextendr, .registration = TRUE) entry NAMESPACE. last section hello_world(). can see roxygen comments copied . Rust function hello_world() arguments R function also arguments. function arguments, generated function wrapper also arguments:","code":"# Generated by extendr: Do not edit by hand # # This file was created with the following call: # .Call(\"wrap__make_myextendr_wrappers\", use_symbols = TRUE, package_name = \"myextendr\") #' @docType package #' @usage NULL #' @useDynLib myextendr, .registration = TRUE NULL #' Return string `\"Hello world!\"` to R. #' @export hello_world <- function() .Call(wrap__hello_world) fn add(x: i32, y: i32) -> i32 { x + y } add <- function(x, y) .Call(wrap__add, x, y)"},{"path":"/dev/articles/package.html","id":"implement-a-new-rust-function","dir":"Articles","previous_headings":"","what":"Implement a new Rust function","title":"Using Rust code in R packages","text":"Now roughly figured extendr works, let’s implement new Rust function. development flow : Modify src/rust/src/lib.rs Run rextendr::document() Run devtools::load_all(\".\") test function exercise, let’s add add(i32, i32) function previous subsection.","code":""},{"path":"/dev/articles/package.html","id":"modify-srcrustsrclib-rs","dir":"Articles","previous_headings":"Implement a new Rust function","what":"1. Modify src/rust/src/lib.rs","title":"Using Rust code in R packages","text":"Add function @export, get exported generated R package. (Without tag, function available internally package programming externally users package.) Don’t forget add function extendr_module!:","code":"/// @export #[extendr] fn add(x: i32, y: i32) -> i32 { x + y } extendr_module! { mod myextendr; fn hello_world; fn add; }"},{"path":"/dev/articles/package.html","id":"run-rextendrdocument","dir":"Articles","previous_headings":"Implement a new Rust function","what":"2. Run rextendr::document()","title":"Using Rust code in R packages","text":"Just run command:","code":"rextendr::document()"},{"path":"/dev/articles/package.html","id":"run-devtoolsload_all--and-test-the-function","dir":"Articles","previous_headings":"Implement a new Rust function","what":"3. Run devtools::load_all(\".\") and test the function","title":"Using Rust code in R packages","text":"Now can load package call add():","code":"devtools::load_all(\".\") add(1L, 2L) #> [1] 3"},{"path":"/dev/articles/rmarkdown.html","id":"evaluating-rust-statements","dir":"Articles","previous_headings":"","what":"Evaluating Rust statements","title":"Using Rust code in R Markdown documents","text":"Chunks type extendr evaluate block Rust statements. value last statement can returned R printed chunk output. example: chunk look knitted document follows: background, extendr knit engine casts Rust integer variable type Result returns value R. Notice lack semicolon (;) end line, indicate want return value. can also write code doesn’t return result R. case, last line end semicolon, example:","code":"```{extendr} rprintln!(\"Hello from Rust!\"); let x = 5; let y = 7; let z = x*y; z ``` rprintln!(\"Hello from Rust!\"); let x = 5; let y = 7; let z = x*y; z ## Hello from Rust! ## [1] 35 let x = 5; let y = 7; let z = x*y; rprintln!(\"{}*{} = {}\", x, y, z); ## 5*7 = 35"},{"path":"/dev/articles/rmarkdown.html","id":"accessing-r-values-from-rust","dir":"Articles","previous_headings":"","what":"Accessing R values from Rust","title":"Using Rust code in R Markdown documents","text":"possible access variables defined R Rust. Let’s define two R variables, numeric string: can read variables Rust using R!() macro. Unfortunately, takes bit error checking type-converting get native Rust values. case things go wrong step. ’re handling errors ?. example, R!() calls R interpreter generate error. even returns value, ’re guaranteed value can coerced real value string. However, as_real() as_str() don’t return errors, return options, need turn None option error via ok_or().","code":"x <- 5.3 y <- \"hello\" let x:f64 = R!(x)? .as_real() .ok_or(\"expected a real\")?; let y:String = R!(y)? .as_str() .ok_or(\"expected a string reference\")? .to_string(); rprintln!(\"The value of x: {}\\nThe value of y: {}\", x, y); ## The value of x: 5.3 ## The value of y: hello"},{"path":"/dev/articles/rmarkdown.html","id":"chaining-chunks-together","dir":"Articles","previous_headings":"","what":"Chaining chunks together","title":"Using Rust code in R Markdown documents","text":"may sometimes want break block Rust code separate Markdown chunks treat one compile unit. can including code one chunk compile unit another, specifying preamble chunk option. option takes character vector chunk names, get included compile unit order provided. Consider example Markdown code: produces following output. Define variable x: Define variable y: Print:","code":"Define variable `x`: ```{extendr chunk_x, eval = FALSE} let x = 1; ``` Define variable `y`: ```{extendr chunk_y, eval = FALSE} let y = 2; ``` Print: ```{extendr out, preamble = c(\"chunk_x\", \"chunk_y\")} rprintln!(\"x = {}, y = {}\", x, y); ``` let x = 1; let y = 2; rprintln!(\"x = {}, y = {}\", x, y); ## x = 1, y = 2"},{"path":"/dev/articles/rmarkdown.html","id":"exporting-rust-functions-or-objects-to-r","dir":"Articles","previous_headings":"","what":"Exporting Rust functions or objects to R","title":"Using Rust code in R Markdown documents","text":"chunk type extendrsrc compiles Rust functions objects registers R called later. example, consider code chunk. creates R functions hello() foo(), well class called Counter. output chunk creates Rust source code: However, now can call functions hello() foo() R use Counter object: code requires external crates, can set dependencies via engine.opts chunk option, like : , Rust code chunk just outputs source: generated functions can used R:","code":"```{extendrsrc} #[extendr] fn hello() -> &'static str { \"Hello from Rust!\" } #[extendr] fn foo(a: &str, b: i64) { rprintln!(\"Data sent to Rust: {}, {}\", a, b); } struct Counter { n: i32, } #[extendr] impl Counter { fn new() -> Self { Self { n: 0 } } fn increment(&mut self) { self.n += 1; } fn get(&self) -> i32 { self.n } } ``` #[extendr] fn hello() -> &'static str { \"Hello from Rust!\" } #[extendr] fn foo(a: &str, b: i64) { rprintln!(\"Data sent to Rust: {}, {}\", a, b); } struct Counter { n: i32, } #[extendr] impl Counter { fn new() -> Self { Self { n: 0 } } fn increment(&mut self) { self.n += 1; } fn get(&self) -> i32 { self.n } } out <- hello() out ## [1] \"Hello from Rust!\" foo(out, nchar(out)) ## Data sent to Rust: Hello from Rust!, 16 x <- Counter$new() x$get() ## [1] 0 x$increment() x$increment() x$get() ## [1] 2 ```{extendrsrc engine.opts = list(dependencies = list(`pulldown-cmark` = \"0.8\"))} 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 } ``` 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 } md_text <- \"# The story of the fox The quick brown fox **jumps over** the lazy dog. The quick *brown fox* jumps over the lazy dog.\" md_to_html(md_text) ## [1] \"

    The story of the fox<\/h1>\\n

    The quick brown fox jumps over<\/strong> the lazy dog.\\nThe quick brown fox<\/em> jumps over the lazy dog.<\/p>\\n\""},{"path":"/dev/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Claus O. Wilke. Author. Andy Thomason. Author. Mossa M. Reimert. Author. Ilia Kosenkov. Author, maintainer. Malcolm Barrett. Author. Josiah Parry. Contributor.","code":""},{"path":"/dev/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Wilke C, Thomason , Reimert M, Kosenkov , Barrett M (2024). rextendr: Call Rust Code R using 'extendr' Crate. R package version 0.3.1.9000, https://extendr.github.io/rextendr/.","code":"@Manual{, title = {rextendr: Call Rust Code from R using the 'extendr' Crate}, author = {Claus O. Wilke and Andy Thomason and Mossa M. Reimert and Ilia Kosenkov and Malcolm Barrett}, year = {2024}, note = {R package version 0.3.1.9000}, url = {https://extendr.github.io/rextendr/}, }"},{"path":[]},{"path":"/dev/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Call Rust Code from R using the extendr Crate","text":"install release version CRAN, run: use remotes can also install rextendr r-universe: Latest development version can installed GitHub: execute Rust code, also need set working Rust toolchain. See installation instructions libR-sys help. can successfully build libR-sys ’re good.","code":"install.packages(\"rextendr\") remotes::install_cran(\"rextendr\") install.packages('rextendr', repos = c('https://extendr.r-universe.dev', 'https://cloud.r-project.org')) remotes::install_github(\"extendr/rextendr\")"},{"path":[]},{"path":"/dev/index.html","id":"sitrep","dir":"","previous_headings":"Usage","what":"Sitrep","title":"Call Rust Code from R using the extendr Crate","text":"good first step check status Rust toolchain available targets using rust_sitrep(). everything OK, see something like : , instance, toolchain found, see something like : Finally, missing required target (platforms Windows rextendr uses default target), report resemble following:","code":"rust_sitrep() # Rust infrastructure sitrep: # ✔ \"rustup\": 1.26.0 (5af9b9484 2023-04-05) # ✔ \"cargo\": 1.72.0 (103a7ff2e 2023-08-15) # ℹ host: x86_64-pc-windows-msvc # ℹ toolchain: stable-x86_64-pc-windows-msvc (default) # ℹ target: x86_64-pc-windows-gnu rust_sitrep() # Rust infrastructure sitrep: # ✔ \"rustup\": 1.26.0 (5af9b9484 2023-04-05) # ✔ \"cargo\": 1.72.0 (103a7ff2e 2023-08-15) # ℹ host: x86_64-pc-windows-msvc # ! Toolchain stable-x86_64-pc-windows-msvc is required to be installed and set as default # ℹ Run `rustup toolchain install stable-x86_64-pc-windows-msvc` to install it # ℹ Run `rustup default stable-x86_64-pc-windows-msvc` to make it default rust_sitrep() # Rust infrastructure sitrep: # ✔ \"rustup\": 1.26.0 (5af9b9484 2023-04-05) # ✔ \"cargo\": 1.72.0 (103a7ff2e 2023-08-15) # ℹ host: x86_64-pc-windows-msvc # i toolchains: nightly-x86_64-pc-windows-msvc and stable-x86_64-pc-windows-msvc (default) # i targets: x86_64-pc-windows-msvc and i686-pc-windows-msvc # ! Target x86_64-pc-windows-gnu is required on this host machine # i Run `rustup target add x86_64-pc-windows-gnu` to install it"},{"path":"/dev/index.html","id":"code-examples","dir":"","previous_headings":"Usage","what":"Code examples","title":"Call Rust Code from R using the extendr Crate","text":"Basic use example: Something sophisticated: package also enables new chunk type knitr, extendr, compiles evaluates Rust code. example, code chunk one: create following output knitted document:","code":"library(rextendr) # create a Rust function rust_function(\"fn add(a:f64, b:f64) -> f64 { a + b }\") # call it from R add(2.5, 4.7) #> [1] 7.2 library(rextendr) # Rust function that computes a sum of integer or double vectors, preserving the type rust_function( \"fn get_sum(x : Either) -> Either { match x { Either::Left(x) => Either::Left(x.iter().sum()), Either::Right(x) => Either::Right(x.iter().sum()), } }\", use_dev_extendr = TRUE, # Use development version of extendr from GitHub features = \"either\", # Enable support for Either crate ) x <- 1:5 y <- c(1, 2, 3, 4, 5) tibble::tibble( Name = c(\"x\", \"y\"), Data = list(x, y), Types = purrr::map_chr(Data, typeof), Sum = purrr::map(Data, get_sum), SumRaw = purrr::flatten_dbl(Sum), ResultType = purrr::map_chr(Sum, typeof) ) #> # A tibble: 2 × 6 #> Name Data Types Sum SumRaw ResultType #> #> 1 x integer 15 integer #> 2 y double 15 double ```{extendr} rprintln!(\"Hello from Rust!\"); let x = 5; let y = 7; let z = x*y; z ``` rprintln!(\"Hello from Rust!\"); let x = 5; let y = 7; let z = x*y; z #> Hello from Rust! #> [1] 35"},{"path":"/dev/index.html","id":"see-also","dir":"","previous_headings":"","what":"See also","title":"Call Rust Code from R using the extendr Crate","text":"cargo-framework associated R package cargo r-rust organization Please note project released Contributor Code Conduct. participating project agree abide terms.","code":""},{"path":"/dev/principles.html","id":null,"dir":"","previous_headings":"","what":"rextendr design prinicples","title":"rextendr design prinicples","text":"guide documents important internal coding conventions used rextendr.","code":""},{"path":"/dev/principles.html","id":"communicating-with-the-user","dir":"","previous_headings":"","what":"Communicating with the user","title":"rextendr design prinicples","text":"rextendr uses cli package format messages user, generally routed rlang::inform(). UI happen ui_*() functions: {cli} supports glue-based interpolation inline text formatting.","code":""},{"path":"/dev/principles.html","id":"throwing-and-testing-errors","dir":"","previous_headings":"","what":"Throwing and testing errors","title":"rextendr design prinicples","text":"Pass errors via cli::cli_abort(). Ensure class rextendr_error specified. can also add details providing named vector. See ?cli::cli_abort() ?cli::cli_bulelts() message argument.","code":"cli::cli_abort( c( \"Unable to register the extendr module.\", \"x\" = \"Could not find file {.file src/entrypoint.c}.\", \"*\" = \"Are you sure this package is using extendr Rust code?\" ), class = \"rextendr_error\" )"},{"path":"/dev/principles.html","id":"silencing-messages","dir":"","previous_headings":"","what":"Silencing messages","title":"rextendr design prinicples","text":"cli used verbosely inform user. user able optionally silence functions particularly verbose output setting quiet argument TRUE—see ?rust_source example. Silencing cli output done helper local_quiet_cli(quiet). quiet = TRUE , cli output suppressed.","code":""},{"path":"/dev/reference/clean.html","id":null,"dir":"Reference","previous_headings":"","what":"Clean Rust binaries and package cache. — clean","title":"Clean Rust binaries and package cache. — clean","text":"Removes Rust binaries (.dll/.libraries), C wrapper object files, invokes cargo clean reset cargo target directory (found default pkg_root/src/rust/target/). Useful Rust code recompiled scratch.","code":""},{"path":"/dev/reference/clean.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Clean Rust binaries and package cache. — clean","text":"","code":"clean(path = \".\")"},{"path":"/dev/reference/clean.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Clean Rust binaries and package cache. — clean","text":"path [ string ] Path package root.","code":""},{"path":"/dev/reference/cran.html","id":null,"dir":"Reference","previous_headings":"","what":"Use CRAN compliant defaults — cran","title":"Use CRAN compliant defaults — cran","text":"Modifies extendr package use CRAN compliant settings.","code":""},{"path":"/dev/reference/cran.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Use CRAN compliant defaults — cran","text":"","code":"use_cran_defaults(path = \".\", quiet = FALSE, overwrite = NULL, lib_name = NULL) vendor_pkgs(path = \".\", quiet = FALSE, overwrite = NULL)"},{"path":"/dev/reference/cran.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Use CRAN compliant defaults — cran","text":"path File path package generate wrapper code. quiet Logical indicating whether progress messages generated . overwrite Logical scalar NULL indicating whether files path overwritten. NULL (default), function ask user whether file overwritten interactive session nothing non-interactive session. FALSE file already exists, function nothing. TRUE, files overwritten. lib_name String used name Rust library. NULL, sanitized R package name used instead.","code":""},{"path":"/dev/reference/cran.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Use CRAN compliant defaults — cran","text":"vendor_pkgs() returns data.frame two columns crate version use_cran_defaults() returns NULL used solely side effects","code":""},{"path":"/dev/reference/cran.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Use CRAN compliant defaults — cran","text":"use_cran_defaults() modifies existing package provide CRAN complaint settings files. creates configure configure.win files well modifies Makevars Makevars.win use required CRAN settings. vendor_pkgs() used package dependencies required CRAN. executes cargo vendor behalf creating vendor/ directory compressed vendor.tar.xz shipped package . modified dependencies, need need repackage","code":""},{"path":"/dev/reference/cran.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Use CRAN compliant defaults — cran","text":"","code":"if (interactive()) { use_cran_defaults() vendor_pkgs() }"},{"path":"/dev/reference/document.html","id":null,"dir":"Reference","previous_headings":"","what":"Compile Rust code and generate package documentation. — document","title":"Compile Rust code and generate package documentation. — document","text":"function rextendr::document() updates package documentation R package uses extendr code, taking account changes made Rust code. wrapper devtools::document(), executes extendr-specific routines calling devtools::document(). Specifically, ensures Rust code recompiled (necessary) --date R wrappers generated regenerating package documentation.","code":""},{"path":"/dev/reference/document.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compile Rust code and generate package documentation. — document","text":"","code":"document(pkg = \".\", quiet = FALSE, roclets = NULL)"},{"path":"/dev/reference/document.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compile Rust code and generate package documentation. — document","text":"pkg package use, can file path package package object. See .package() information. quiet TRUE suppresses output function. roclets Character vector roclet names use package. default, NULL, uses roxygen roclets option, defaults c(\"collate\", \"namespace\", \"rd\").","code":""},{"path":"/dev/reference/document.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compile Rust code and generate package documentation. — document","text":"return value, called side effects.","code":""},{"path":"/dev/reference/eng_extendr.html","id":null,"dir":"Reference","previous_headings":"","what":"Knitr engines — eng_extendr","title":"Knitr engines — eng_extendr","text":"Two knitr engines enable code chunks type extendr (individual Rust statements evaluated via rust_eval()) extendrsrc (Rust functions classes exported R via rust_source()).","code":""},{"path":"/dev/reference/eng_extendr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Knitr engines — eng_extendr","text":"","code":"eng_extendr(options) eng_extendrsrc(options)"},{"path":"/dev/reference/eng_extendr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Knitr engines — eng_extendr","text":"options list chunk options.","code":""},{"path":"/dev/reference/eng_extendr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Knitr engines — eng_extendr","text":"character string representing engine output.","code":""},{"path":"/dev/reference/inf_dev_extendr_used.html","id":null,"dir":"Reference","previous_headings":"","what":"Inform the user that a development version of extendr is being used. — inf_dev_extendr_used","title":"Inform the user that a development version of extendr is being used. — inf_dev_extendr_used","text":"function returns string used inside cli function. See validate_extendr_features() example.","code":""},{"path":"/dev/reference/inf_dev_extendr_used.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Inform the user that a development version of extendr is being used. — inf_dev_extendr_used","text":"","code":"inf_dev_extendr_used()"},{"path":"/dev/reference/local_quiet_cli.html","id":null,"dir":"Reference","previous_headings":"","what":"Silence {cli} output — local_quiet_cli","title":"Silence {cli} output — local_quiet_cli","text":"Use functions use cli output optionally suppressed.","code":""},{"path":"/dev/reference/local_quiet_cli.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Silence {cli} output — local_quiet_cli","text":"","code":"local_quiet_cli(quiet, env = rlang::caller_env())"},{"path":"/dev/reference/local_quiet_cli.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Silence {cli} output — local_quiet_cli","text":"","code":"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) }"},{"path":"/dev/reference/make_module_macro.html","id":null,"dir":"Reference","previous_headings":"","what":"Generate extendr module macro for Rust source — make_module_macro","title":"Generate extendr module macro for Rust source — make_module_macro","text":"Read Rust source code, find functions implementations #[extendr] attribute, generate extendr_module! macro statement.","code":""},{"path":"/dev/reference/make_module_macro.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generate extendr module macro for Rust source — make_module_macro","text":"","code":"make_module_macro(code, module_name = \"rextendr\")"},{"path":"/dev/reference/make_module_macro.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generate extendr module macro for Rust source — make_module_macro","text":"code Character vector containing Rust code. module_name Module name","code":""},{"path":"/dev/reference/make_module_macro.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Generate extendr module macro for Rust source — make_module_macro","text":"Character vector holding contents generated macro statement.","code":""},{"path":"/dev/reference/make_module_macro.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Generate extendr module macro for Rust source — make_module_macro","text":"function uses simple regular expressions Rust parsing can get confused valid Rust code. meant convenience simple use cases. particular, currently handle implementations generics.","code":""},{"path":"/dev/reference/register_extendr.html","id":null,"dir":"Reference","previous_headings":"","what":"Register the extendr module of a package with R — register_extendr","title":"Register the extendr module of a package with R — register_extendr","text":"function generates wrapper code corresponding extendr module R package. useful package development, generally want appropriate R code wrapping Rust functions implemented via extendr. development settings, want call function directly, instead call rextendr::document().","code":""},{"path":"/dev/reference/register_extendr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Register the extendr module of a package with R — register_extendr","text":"","code":"register_extendr(path = \".\", quiet = FALSE, force = FALSE, compile = NA)"},{"path":"/dev/reference/register_extendr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Register the extendr module of a package with R — register_extendr","text":"path Path package root looked . quiet Logical indicating whether progress messages generated . force Logical indicating whether force regenerating R/extendr-wrappers.R even seem need updated. (default, generation skipped newer DLL). compile Logical indicating whether recompile DLLs: TRUE always recompiles NA recompiles needed (.e., source files manifest file newer DLL) FALSE never recompiles","code":""},{"path":"/dev/reference/register_extendr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Register the extendr module of a package with R — register_extendr","text":"(Invisibly) Path file containing generated wrappers.","code":""},{"path":"/dev/reference/register_extendr.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Register the extendr module of a package with R — register_extendr","text":"function register_extendr() compiles package Rust code required, wrapper code retrieved compiled Rust code saved R/extendr-wrappers.R. Afterwards, re-document re-install package wrapper functions take effect.","code":""},{"path":[]},{"path":"/dev/reference/rextendr.html","id":null,"dir":"Reference","previous_headings":"","what":"Call Rust code from R using the 'extendr' Crate — rextendr","title":"Call Rust code from R using the 'extendr' Crate — rextendr","text":"rextendr package implements functions interface Rust code R. See rust_source() details.","code":""},{"path":[]},{"path":"/dev/reference/rextendr.html","id":"author","dir":"Reference","previous_headings":"","what":"Author","title":"Call Rust code from R using the 'extendr' Crate — rextendr","text":"Maintainer: Ilia Kosenkov ilia.kosenkov@outlook.com (ORCID) Authors: Claus O. Wilke wilke@austin.utexas.edu (ORCID) Andy Thomason andy@andythomason.com Mossa M. Reimert mossa@sund.ku.dk Malcolm Barrett malcolmbarrett@gmail.com (ORCID) contributors: Josiah Parry (ORCID) [contributor]","code":""},{"path":"/dev/reference/rust_eval.html","id":null,"dir":"Reference","previous_headings":"","what":"Evaluate Rust code — rust_eval","title":"Evaluate Rust code — rust_eval","text":"Compile evaluate one Rust expressions. last expression Rust code returns value (.e., end ;), value returned R. value returned need type Robj, long can cast type .(). conversion done automatically, worry code.","code":""},{"path":"/dev/reference/rust_eval.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Evaluate Rust code — rust_eval","text":"","code":"rust_eval(code, env = parent.frame(), ...)"},{"path":"/dev/reference/rust_eval.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Evaluate Rust code — rust_eval","text":"code Input rust code. env R environment Rust code evaluated. ... parameters handed rust_function().","code":""},{"path":"/dev/reference/rust_eval.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Evaluate Rust code — rust_eval","text":"return value generated Rust code.","code":""},{"path":"/dev/reference/rust_eval.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Evaluate Rust code — rust_eval","text":"","code":"if (FALSE) { # \\dontrun{ # Rust code without return value, called only for its side effects rust_eval( code = 'rprintln!(\"hello from Rust!\");' ) # Rust code with return value rust_eval( code = \" let x = 5; let y = 7; let z = x * y; z // return to R; rust_eval() takes care of type conversion code \" ) } # }"},{"path":"/dev/reference/rust_sitrep.html","id":null,"dir":"Reference","previous_headings":"","what":"Report on Rust infrastructure — rust_sitrep","title":"Report on Rust infrastructure — rust_sitrep","text":"Prints detailed report state Rust infrastructure host machine.","code":""},{"path":"/dev/reference/rust_sitrep.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Report on Rust infrastructure — rust_sitrep","text":"","code":"rust_sitrep()"},{"path":"/dev/reference/rust_sitrep.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Report on Rust infrastructure — rust_sitrep","text":"Nothing","code":""},{"path":"/dev/reference/rust_source.html","id":null,"dir":"Reference","previous_headings":"","what":"Compile Rust code and call from R — rust_source","title":"Compile Rust code and call from R — rust_source","text":"rust_source() compiles loads single Rust file use R. rust_function() compiles loads single Rust function use R.","code":""},{"path":"/dev/reference/rust_source.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compile Rust code and call from R — rust_source","text":"","code":"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, ... )"},{"path":"/dev/reference/rust_source.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compile Rust code and call from R — rust_source","text":"file Input rust file source. code Input rust code, used instead file. module_name Name module defined Rust source via extendr_module!. Default \"rextendr\". generate_module_macro FALSE file specified, match exactly name module defined source. dependencies Character vector dependencies lines added Cargo.toml file. patch.crates_io Character vector patch statements crates.io added Cargo.toml file. profile Rust profile. Can either \"dev\", \"release\" \"perf\". default, \"dev\", compiles faster produces slower code. toolchain Rust toolchain. default, NULL, compiles system default toolchain. Accepts valid Rust toolchain qualifiers, \"nightly\", (Windows) \"stable-msvc\". extendr_deps Versions extendr-* crates. Defaults rextendr.extendr_deps option (list(`extendr-api` = \"*\")) use_dev_extendr TRUE, otherwise, uses rextendr.extendr_dev_deps option (list(`extendr-api` = list(git = \"https://github.com/extendr/extendr\")). features vector extendr-api features enabled. Supported values \"ndarray\", \"num-complex\", \"serde\", \"graphics\". Unknown features produce warning quiet TRUE. env R environment wrapping functions defined. use_extendr_api Logical indicating whether use extendr_api::prelude::*; added top Rust source provided via code. Default TRUE. Ignored Rust source provided via file. generate_module_macro Logical indicating whether Rust module macro automatically generated code. Default TRUE. Ignored Rust source provided via file. macro generation done make_module_macro() may fail complex cases. something work, try calling make_module_macro() code see whether generated macro code issues. cache_build Logical indicating whether builds cached calls rust_source(). quiet Logical indicating whether compile output generated . use_rtools Logical indicating whether append path Rtools PATH variable Windows using RTOOLS40_HOME environment variable (set). appended path depends process architecture. nothing platforms. use_dev_extendr Logical indicating whether use development version extendr. effect extendr_deps set. extendr_fn_options list extendr function options inserted #[extendr(...)] attribute ... parameters handed rust_source().","code":""},{"path":"/dev/reference/rust_source.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compile Rust code and call from R — rust_source","text":"result dyn.load(), object class DLLInfo. See getLoadedDLLs() details.","code":""},{"path":"/dev/reference/rust_source.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compile Rust code and call from R — rust_source","text":"","code":"if (FALSE) { # \\dontrun{ # creating a single rust function rust_function(\"fn add(a:f64, b:f64) -> f64 { a + b }\") add(2.5, 4.7) # creating multiple rust functions at once code <- 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 fox The quick brown fox **jumps over** the lazy dog. The quick *brown fox* jumps over the lazy dog.\" md_to_html(md_text) } # }"},{"path":"/dev/reference/to_toml.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert R list() into toml-compatible format. — to_toml","title":"Convert R list() into toml-compatible format. — to_toml","text":"to_toml() can used build Cargo.toml. cargo manifest can represented terms R objects, allowing limited validation syntax verification. function converts manifests written using R objects toml representation, applying basic formatting, ideal generating cargo manifests runtime.","code":""},{"path":"/dev/reference/to_toml.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert R list() into toml-compatible format. — to_toml","text":"","code":"to_toml(..., .str_as_literal = TRUE, .format_int = \"%d\", .format_dbl = \"%g\")"},{"path":"/dev/reference/to_toml.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert R list() into toml-compatible format. — to_toml","text":"... list toml constructed. Supports nesting tidy evaluation. .str_as_literal Logical indicating whether treat strings literal (single quotes escapes) basic (escaping sequences) ones. Default TRUE. .format_int, .format_dbl Character scalar describing number formatting. Compatible sprintf.","code":""},{"path":"/dev/reference/to_toml.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert R list() into toml-compatible format. — to_toml","text":"character vector, element corresponds one line resulting output.","code":""},{"path":"/dev/reference/to_toml.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Convert R list() into toml-compatible format. — to_toml","text":"","code":"# Produces [workspace] with no children to_toml(workspace = NULL) #> [workspace] to_toml(patch.crates_io = list(`extendr-api` = list(git = \"git-ref\"))) #> [patch.crates_io] #> extendr-api = { git = 'git-ref' } # Single-element arrays are distinguished from scalars # using explicitly set `dim` to_toml(lib = list(`crate-type` = array(\"cdylib\", 1))) #> [lib] #> crate-type = [ 'cdylib' ]"},{"path":"/dev/reference/use_extendr.html","id":null,"dir":"Reference","previous_headings":"","what":"Set up a package for use with Rust extendr code — use_extendr","title":"Set up a package for use with Rust extendr code — use_extendr","text":"Create scaffolding needed add Rust extendr code R package. use_extendr() adds small Rust library single Rust function returns string \"Hello world!\". also adds wrapper code Rust function can called R hello_world().","code":""},{"path":"/dev/reference/use_extendr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Set up a package for use with Rust extendr code — use_extendr","text":"","code":"use_extendr( path = \".\", crate_name = NULL, lib_name = NULL, quiet = FALSE, overwrite = NULL, edition = c(\"2021\", \"2018\") )"},{"path":"/dev/reference/use_extendr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Set up a package for use with Rust extendr code — use_extendr","text":"path File path package generate wrapper code. crate_name String used name Rust crate. NULL, sanitized R package name used instead. lib_name String used name Rust library. NULL, sanitized R package name used instead. quiet Logical indicating whether progress messages generated . overwrite Logical scalar NULL indicating whether files path overwritten. NULL (default), function ask user whether file overwritten interactive session nothing non-interactive session. FALSE file already exists, function nothing. TRUE, files overwritten. edition String indicating Rust edition used; Default \"2021\".","code":""},{"path":"/dev/reference/use_extendr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Set up a package for use with Rust extendr code — use_extendr","text":"logical value (invisible) indicating whether package files generated .","code":""},{"path":"/dev/reference/write_license_note.html","id":null,"dir":"Reference","previous_headings":"","what":"Generate LICENSE.note file. — write_license_note","title":"Generate LICENSE.note file. — write_license_note","text":"LICENSE.note generated function contains information Rust crate dependencies. use function, cargo-lincense command must installed.","code":""},{"path":"/dev/reference/write_license_note.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generate LICENSE.note file. — write_license_note","text":"","code":"write_license_note(path = \".\", quiet = FALSE, force = TRUE)"},{"path":"/dev/reference/write_license_note.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generate LICENSE.note file. — write_license_note","text":"path Path package root looked . quiet Logical indicating whether progress messages generated . force Logical indicating whether regenerate LICENSE.note LICENSE.note already exists.","code":""},{"path":"/dev/reference/write_license_note.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Generate LICENSE.note file. — write_license_note","text":"return value, called side effects.","code":""},{"path":"/dev/news/index.html","id":"rextendr-development-version","dir":"Changelog","previous_headings":"","what":"rextendr (development version)","title":"rextendr (development version)","text":"use_extendr() sets DESCRIPTION’s SystemRequirements field according CRAN policy Cargo (Rust's package manager), rustc (#329) Introduces new functions use_cran_defaults() vendor_pkgs() ease publication extendr-powered packages CRAN. See new article CRAN compliant extendr packages use (#320). rust_sitrep() now better communicates status Rust toolchain available targets. also guides user necessary installation steps fix Rust setup (#318). use_extendr() document() now set SystemRequirements field DESCRIPTION file Cargo (rustc package manager) field empty (#298). use_extendr() gets new ability overwrite existing rextendr templates (#292). use_extendr() sets publish = false [package] section Cargo.toml (#297). use_extendr() correctly handles calls path equal \".\" (current folder), active usethis project (#323). Fixes issue pre-defined set known features: added either (#338) create_extendr_package() allows user create project directory using RStudio’s Project Command. (#321) Support RTOOLS44 (#347) Removed use_try_from option rust_function, added use_rng (#354)","code":""},{"path":"/dev/news/index.html","id":"rextendr-030","dir":"Changelog","previous_headings":"","what":"rextendr 0.3.0","title":"rextendr 0.3.0","text":"CRAN release: 2023-05-30 Ilia Kosenkov now official maintainer. Josiah Parry now contributor. Support Rtools43 (#231). rextendr migrated use cli raising errors warnings. Developer note: new helper function local_quiet_cli() introduced R/utils.R simplify silencing cli output.","code":""},{"path":"/dev/news/index.html","id":"new-features-0-3-0","dir":"Changelog","previous_headings":"","what":"New features","title":"rextendr 0.3.0","text":"new function rust_sitrep() prints short report currently installed Rust toolchain (#274). new function write_license_note() generate LICENSE.note file Cargo.toml (#271). extendr_fn_options parameter rust_source() controls type options emitted #[extendr()] attribute (#252). use_dev_extendr flag makes rust_source() family functions compile code using development version extendr. Development configuration stored option named rextendr.extendr_dev_deps (#251). features parameter rust_source() now correctly enables features extendr-api references required crates. features available release version extendr raises warning (#249). -win.def file containing DLL exports created rextendr::use_extendr(). used linking phase Windows solves problem compiling large projects, polars (#212) Support extendr macro options (#128). rust_source() got features argument specify Cargo features activate (#140). rextendr::document() now sets envvars devtools::document() sets, e.g. NOT_CRAN (#135).","code":""},{"path":"/dev/news/index.html","id":"rextendr-020","dir":"Changelog","previous_headings":"","what":"rextendr 0.2.0","title":"rextendr 0.2.0","text":"CRAN release: 2021-06-15 First official release.","code":""}] +[{"path":[]},{"path":"/dev/CODE-OF-CONDUCT.html","id":"our-pledge","dir":"","previous_headings":"","what":"Our Pledge","title":"Contributor Covenant Code of Conduct","text":"contributors maintainers project, pledge make participation community harassment-free experience everyone, regardless age, body size, visible invisible disability, ethnicity, sex characteristics, gender identity expression, level experience, education, socio-economic status, nationality, personal appearance, race, religion, sexual identity orientation. pledge act interact ways contribute open, welcoming, diverse, inclusive, healthy community.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"our-standards","dir":"","previous_headings":"","what":"Our Standards","title":"Contributor Covenant Code of Conduct","text":"Examples behavior contributes positive environment community include: Demonstrating empathy kindness toward people respectful differing opinions, viewpoints, experiences Giving gracefully accepting constructive feedback Accepting responsibility apologizing affected mistakes, learning experience Focusing best just us individuals, overall community Examples unacceptable behavior include: use sexualized language imagery, sexual attention advances kind Trolling, insulting derogatory comments, personal political attacks Public private harassment Publishing others’ private information, physical email address, without explicit permission conduct reasonably considered inappropriate professional setting","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"enforcement-responsibilities","dir":"","previous_headings":"","what":"Enforcement Responsibilities","title":"Contributor Covenant Code of Conduct","text":"Project leaders responsible clarifying enforcing standards acceptable behavior take appropriate fair corrective action response behavior deem inappropriate, threatening, offensive, harmful. Project leaders right responsibility remove, edit, reject comments, commits, code, wiki edits, issues, contributions aligned Code Conduct, communicate reasons moderation decisions appropriate.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"scope","dir":"","previous_headings":"","what":"Scope","title":"Contributor Covenant Code of Conduct","text":"Code Conduct applies within community spaces, also applies individual officially representing community public spaces. Examples representing community include using official e-mail address, posting via official social media account, acting appointed representative online offline event.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"enforcement","dir":"","previous_headings":"","what":"Enforcement","title":"Contributor Covenant Code of Conduct","text":"Instances abusive, harassing, otherwise unacceptable behavior may reported current maintainers project via email. Maintainers email addresses provided DESCRIPTION file. complaints reviewed investigated promptly fairly. community leaders obligated respect privacy security reporter incident.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"enforcement-guidelines","dir":"","previous_headings":"","what":"Enforcement Guidelines","title":"Contributor Covenant Code of Conduct","text":"Community leaders follow Community Impact Guidelines determining consequences action deem violation Code Conduct:","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"id_1-correction","dir":"","previous_headings":"Enforcement Guidelines","what":"1. Correction","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Use inappropriate language behavior deemed unprofessional unwelcome community. Consequence: private, written warning community leaders, providing clarity around nature violation explanation behavior inappropriate. public apology may requested.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"id_2-warning","dir":"","previous_headings":"Enforcement Guidelines","what":"2. Warning","title":"Contributor Covenant Code of Conduct","text":"Community Impact: violation single incident series actions. Consequence: warning consequences continued behavior. interaction people involved, including unsolicited interaction enforcing Code Conduct, specified period time. includes avoiding interactions community spaces well external channels like social media. Violating terms may lead temporary permanent ban.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"id_3-temporary-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"3. Temporary Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: serious violation community standards, including sustained inappropriate behavior. Consequence: temporary ban sort interaction public communication community specified period time. public private interaction people involved, including unsolicited interaction enforcing Code Conduct, allowed period. Violating terms may lead permanent ban.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"id_4-permanent-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"4. Permanent Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Demonstrating pattern violation community standards, including sustained inappropriate behavior, harassment individual, aggression toward disparagement classes individuals. Consequence: permanent ban sort public interaction within community.","code":""},{"path":"/dev/CODE-OF-CONDUCT.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributor Covenant Code of Conduct","text":"Code Conduct adapted Contributor Covenant, version 2.0, available https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. Community Impact Guidelines inspired Mozilla’s code conduct enforcement ladder. answers common questions code conduct, see FAQ https://www.contributor-covenant.org/faq. Translations available https://www.contributor-covenant.org/translations.","code":""},{"path":"/dev/CONTRIBUTING.html","id":null,"dir":"","previous_headings":"","what":"Contributing","title":"Contributing","text":"welcome contributions rextendr project. Contributions come many forms. Please carefully read follow guidelines. help us make contribution process easy effective everyone involved. also communicates agree respect time developers managing developing project.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"quicklinks","dir":"","previous_headings":"","what":"Quicklinks","title":"Contributing","text":"Code Conduct Issues Pull Requests Code Style Getting Help Authorship Attribution","code":""},{"path":"/dev/CONTRIBUTING.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of Conduct","title":"Contributing","text":"take open source community seriously hold contributors high standards communication. participating contributing project, agree uphold Code Conduct.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"getting-started","dir":"","previous_headings":"","what":"Getting Started","title":"Contributing","text":"Contributions can made via Issues Pull Requests (PRs). general guidelines cover : Please search existing Issues PRs creating . work hard makes sure issues handled timely manner , depending problem maintainer availability, take investigate problem. friendly ping comment thread can help draw attention issue received attention . Please keep mind contributors project volunteers may commitments need attend .","code":""},{"path":"/dev/CONTRIBUTING.html","id":"issues","dir":"","previous_headings":"Getting Started","what":"Issues","title":"Contributing","text":"Issues used report problems library, request new feature, discuss potential changes PR created. Please use Issues request user support. Whenever possible, please provide minimal reproducible example (reprex) bug report filing. minimal example, likely somebody else can figure problem , please remove code isn’t relevant problem reporting. Please keep issues focused one particular problem. Don’t feel shy opening multiple issues ’re encountering one problem. find Issue addresses problem ’re , please add reproduction information existing issue rather creating new one. Adding reaction can also help indicating maintainers particular problem affecting just reporter.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"pull-requests","dir":"","previous_headings":"Getting Started","what":"Pull Requests","title":"Contributing","text":"PRs always welcome can quick way get fix improvement slated next release. However, please always open Issue submitting PR. general, PRs : Address single concern least number changed lines possible. fix/add functionality question address wide-spread whitespace/style issues, . Add unit integration tests fixed changed functionality. Include documentation. Indicate Issue address using words Closes # Fixes # body PR /git commit message. (See GitHub Documentation details linking PRs Issues automatically closing Issues merging PRs.) general, follow GitHub flow development model: Fork repository Github account Clone project machine Create branch locally succinct descriptive name Commit changes branch Push changes fork Open PR repository follow PR template can efficiently review changes.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"code-style","dir":"","previous_headings":"Getting Started","what":"Code style","title":"Contributing","text":"New code follow tidyverse style guide. can use styler package apply styles, please don’t restyle code nothing PR. use roxygen2, Markdown syntax, documentation. use testthat unit tests. Contributions test cases included easier accept.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"getting-help","dir":"","previous_headings":"","what":"Getting Help","title":"Contributing","text":"Please join us Discord server general conversations questions don’t belong GitHub issue.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"authorship","dir":"","previous_headings":"","what":"Authorship","title":"Contributing","text":"Contributors made multiple, sustained, /non-trivial contributions project may added author list. New author names always added end list, author order reflects chronological order joining project. authorship decisions discretion current maintainers project.","code":""},{"path":"/dev/CONTRIBUTING.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributing","text":"document adapted General Contributing Guidelines auth0 project.","code":""},{"path":"/dev/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"MIT License","title":"MIT License","text":"Copyright (c) 2020 rextendr authors Permission hereby granted, free charge, person obtaining copy software associated documentation files (“Software”), deal Software without restriction, including without limitation rights use, copy, modify, merge, publish, distribute, sublicense, /sell copies Software, permit persons Software furnished , subject following conditions: copyright notice permission notice shall included copies substantial portions Software. SOFTWARE PROVIDED “”, WITHOUT WARRANTY KIND, EXPRESS IMPLIED, INCLUDING LIMITED WARRANTIES MERCHANTABILITY, FITNESS PARTICULAR PURPOSE NONINFRINGEMENT. EVENT SHALL AUTHORS COPYRIGHT HOLDERS LIABLE CLAIM, DAMAGES LIABILITY, WHETHER ACTION CONTRACT, TORT OTHERWISE, ARISING , CONNECTION SOFTWARE USE DEALINGS SOFTWARE.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"systemrequirements","dir":"Articles","previous_headings":"","what":"SystemRequirements","title":"CRAN compliant extendr packages","text":"Building Rust-backed packages source requires system dependencies cargo rustc. CRAN stipulated preferred way tracking using following line packages DESCRIPTION file. Even though free-form field, consistency can help whole ecosystem keep track Rust-based R packages.","code":"SystemRequirements: Cargo (Rust's package manager), rustc"},{"path":"/dev/articles/cran-compliance.html","id":"cargo-and-rustc-availability","dir":"Articles","previous_headings":"","what":"cargo and rustc availability","title":"CRAN compliant extendr packages","text":"order R package built source, cargo rustc need available machine compiling package. expectation R packages using external dependencies configure configure.win files check dependencies available attempting compile package. checks fail, build process stopped prematurely. CRAN expects cargo PATH, user’s home directory checked ~/.cargo/bin. configuration files must perform checks.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"cargo-build-settings","dir":"Articles","previous_headings":"","what":"cargo build settings","title":"CRAN compliant extendr packages","text":"CRAN also imposes restrictions cargo builds crates. CRAN requested two logical CPUs used build process. default, cargo uses multiple threads speed compilation process. CRAN policy allows maximum two. set using -j 2 option, passed cargo build. Additionally, minimize security risks ensure package stability, CRAN requires packages built completely offline. prevents external dependencies downloaded compile time. requirement, vendored dependencies must used.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"vendored-dependencies","dir":"Articles","previous_headings":"","what":"Vendored dependencies","title":"CRAN compliant extendr packages","text":"Vendoring dependencies act including dependency package source code. case Rust, dependencies fetched compile time. enable compilation offline environment, dependencies must vendored, accomplished using cargo vendor command. cargo vendor creates local directory default name vendor, contains source code recursive dependencies crate built. CRAN compatibility, vendor directory must compressed using tar xz compression included source package. build time, dependencies extracted, compiled, discarded. process controlled Makevars Makevars.win files.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"package-compilation","dir":"Articles","previous_headings":"","what":"Package compilation","title":"CRAN compliant extendr packages","text":"comes together package compilation time, providing following requirements met: cargo must able called user’s home directory user’s home directory must modified written package must compiled offline two logical CPUs used versions cargo rustc printed","code":""},{"path":"/dev/articles/cran-compliance.html","id":"using-cran-defaults","dir":"Articles","previous_headings":"","what":"Using CRAN defaults","title":"CRAN compliant extendr packages","text":"rextendr provides default CRAN compliant scaffolding via use_cran_defaults() function appropriate vendoring vendor_pkgs().","code":""},{"path":"/dev/articles/cran-compliance.html","id":"making-a-package-cran-compliant","dir":"Articles","previous_headings":"Using CRAN defaults","what":"Making a package CRAN compliant","title":"CRAN compliant extendr packages","text":"create CRAN compliant R package begin creating new R package. calling usethis::create_package(). new R project, run rextendr::use_extendr() create minimal scaffolding necessary Rust-powered R package. done , can now run rextendr::use_cran_defaults(). use_cran_defaults() create configure configure.win files. Additionally, create new Makevars Makevars.win print versions cargo rustc well use cargo build argument -j 2 --offline.","code":""},{"path":"/dev/articles/cran-compliance.html","id":"vendoring-packages","dir":"Articles","previous_headings":"Using CRAN defaults","what":"Vendoring packages","title":"CRAN compliant extendr packages","text":"configured R package use CRAN defaults, need vendor dependencies. vendor_pkgs() runs cargo vendor behalf, compresses vendor/ directory, updates vendor-config.toml file accordingly. added new dependencies, changed version source crates, use vendor_pkgs() . ensures compressed vendor.tar.xz contains updates . important CI publishing CRAN.","code":""},{"path":"/dev/articles/package.html","id":"create-a-template-package","dir":"Articles","previous_headings":"","what":"Create a template package","title":"Using Rust code in R packages","text":"Creating R package extendr easy rextendr package. First, create empty R package. can usethis::create_package(). Let’s pick myextendr package name. , execute rextendr::use_extendr() inside package directory create scaffolding use extendr. developers use RStudio, also provide project template call usethis::create_package() rextendr::use_extendr() . done using RStudio’s Create Project command, can find global toolbar File menu. Choose “New Directory” select “R package extendr.” can fill details match preferences. project directory setup, strongly encourage run rextendr::rust_sitrep() console. provide detailed report current state Rust infrastructure, along helpful advice address issues may arise. Assuming proper installation Rust, just one step away calling Rust functions R. message says, need run rextendr::document(). , moving forward, let’s look files added.","code":"usethis::create_package(\"path/to/myextendr\") rextendr::use_extendr() #> ✓ Creating src/rust/src. #> ✓ Setting active project to 'path/to/myextendr' #> ✓ Writing 'src/entrypoint.c' #> ✓ Writing 'src/Makevars' #> ✓ Writing 'src/Makevars.win' #> ✓ Writing 'src/.gitignore' #> ✓ Writing src/rust/Cargo.toml. #> ✓ Writing 'src/rust/src/lib.rs' #> ✓ Writing 'R/extendr-wrappers.R' #> ✓ Finished configuring extendr for package myextendr. #> • Please update the system requirement in DESCRIPTION file. #> • Please run `rextendr::document()` for changes to take effect."},{"path":"/dev/articles/package.html","id":"package-structure","dir":"Articles","previous_headings":"","what":"Package structure","title":"Using Rust code in R packages","text":"following files added rextendr::use_extendr(): R/extendr-wrappers.R: file contains auto-generated R functions Rust code. don’t modify file hand. src/Makevars, src/Makevars.win: files hook cargo build installation R package. cases, don’t edit . src/entrypoint.c: file needed avoid linker removing static library. 99.9% cases, don’t edit (except changing crate name). src/rust/: Rust code crate using extendr-api. mainly write code. , short, really look two files:","code":". ├── R │ └── extendr-wrappers.R ... └── src ├── Makevars ├── Makevars.win ├── entrypoint.c └── rust ├── Cargo.toml └── src └── lib.rs"},{"path":"/dev/articles/package.html","id":"srcrustcargo-toml","dir":"Articles","previous_headings":"Package structure","what":"src/rust/Cargo.toml","title":"Using Rust code in R packages","text":"crate name name R package’s name default. can change , might bit cumbersome tweak files accordingly, recommend leaving . probably want specify concrete extendr version, example extendr-api = '0.2'. try development version extendr, can modify last line read","code":"[package] name = 'myextendr' version = '0.1.0' edition = '2021' [lib] crate-type = [ 'staticlib' ] [dependencies] extendr-api = '*' extendr-api = { git = 'https://github.com/extendr/extendr' }"},{"path":"/dev/articles/package.html","id":"srcrustsrclib-rs","dir":"Articles","previous_headings":"Package structure","what":"src/rust/src/lib.rs","title":"Using Rust code in R packages","text":"Let’s explain file line line. first line, containing use statement, declares commonly used extendr API functions Rust compiler. Next, may notice / repeated three times, usual Rust comments require two slashes (.e., //). one Rust’s “doc comment” notation generate crate’s documentation. extendr, lines copied auto-generated R code roxygen comments. analogous Rcpp/cpp11’s //'. next line core extendr’s mechanism. function marked macro, corresponding R function generated automatically. analogous Rcpp’s [[Rcpp::export]] cpp11’s [[cpp11::register]]. last 3 lines macro generating exports, comment explains. implement another function just hello_world, needs listed well marking #[extendr] macro.","code":"use extendr_api::prelude::*; /// Return string `\"Hello world!\"` to R. /// @export #[extendr] fn hello_world() -> &'static str { \"Hello world!\" } // Macro to generate exports. // This ensures exported functions are registered with R. // See corresponding C code in `entrypoint.c`. extendr_module! { mod myextendr; fn hello_world; } use extendr_api::prelude::*; /// Return string `\"Hello world!\"` to R. /// @export #[extendr] // Macro to generate exports. // This ensures exported functions are registered with R. // See corresponding C code in `entrypoint.c`. extendr_module! { mod myextendr; fn hello_world; }"},{"path":[]},{"path":"/dev/articles/package.html","id":"compile","dir":"Articles","previous_headings":"Compile and use the package","what":"Compile","title":"Using Rust code in R packages","text":"Compiling Rust code R functions easy executing one command: might wonder compilation triggered function name just document(). Well, compilation actually needed generate documentation R wrapper code Rust code. consistent behavior devtools::document() packages using C C++. , following files updated generated: src/rust/target/release/libmyextendr.(extension depends OS): static library built Rust code. used compiling shared object myextendr.. src/myextendr.(extension depends OS): shared object actually called R. R/extendr-wrappers.R: auto-generated R functions, including roxygen comments, go file. roxygen comments accordingly converted Rd files NAMESPACE. man/, NAMESPACE: generated roxygen comments.","code":"rextendr::document() #> ✓ Saving changes in the open files. #> ℹ Generating extendr wrapper functions for package: myextendr. #> ! No library found at src/myextendr.so, recompilation is required. #> Re-compiling myextendr #> ─ installing *source* package ‘myextendr’ ... (347ms) #> ** using staged installation #> ** libs #> rm -Rf myextendr.so ./rust/target/release/libmyextendr.a entrypoint.o #> gcc -std=gnu99 -I\"/usr/share/R/include\" -DNDEBUG -fpic -g -O2 -fdebug-prefix-map=/build/r-base-tbZjLv/r-base-4.1.0=. #> -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -UNDEBUG -Wall -pedantic -g -O0 #> -fdiagnostics-color=always -c entrypoint.c -o entrypoint.o #> cargo build --lib --release --manifest-path=./rust/Cargo.toml #> Updating crates.io index #> Compiling proc-macro2 v1.0.27 #> Compiling unicode-xid v0.2.2 #> Compiling libR-sys v0.2.1 #> Compiling syn v1.0.72 #> Compiling extendr-engine v0.2.0 #> Compiling lazy_static v1.4.0 #> Compiling quote v1.0.9 #> Compiling extendr-macros v0.2.0 #> Compiling extendr-api v0.2.0 #> Compiling myextendr v0.1.0 (path/to/myextendr/src/rust) #> Finished release [optimized] target(s) in 19.05s #> gcc -std=gnu99 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o myextendr.so entrypoint.o -L./rust/target/release #> -lmyextendr -L/usr/lib/R/lib -lR #> installing to /tmp/RtmpfMcL08/devtools_install_e2d6351b843c/00LOCK-myextendr/00new/myextendr/libs #> ** checking absolute paths in shared objects and dynamic libraries #> ─ DONE (myextendr) #> ✓ Writing 'R/extendr-wrappers.R'. #> ℹ Updating myextendr documentation #> ℹ Loading myextendr #> Writing NAMESPACE #> Writing NAMESPACE #> Writing hello_world.Rd . ... ├── NAMESPACE ----------(4) ├── R │ └── extendr-wrappers.R ----------(3) ├── man │ └── hello_world.Rd ----------(4) └── src ├── myextendr.so ----------(2) └── rust └── target └── release ├── libmyextendr.a ---(1) ..."},{"path":"/dev/articles/package.html","id":"load-and-use","dir":"Articles","previous_headings":"Compile and use the package","what":"Load and use","title":"Using Rust code in R packages","text":"running rextendr::document(), can just load package devtools::load_all() (alternatively install call library()) call function implemented Rust.","code":"devtools::load_all(\".\") hello_world() #> [1] \"Hello world!\""},{"path":"/dev/articles/package.html","id":"rust-code-vs-generated-r-code","dir":"Articles","previous_headings":"","what":"Rust code vs generated R code","title":"Using Rust code in R packages","text":"never edit R wrapper code hand, might good know R code generated Rust code. Let’s look R/extendr-wrappers.R: , .Call(\"wrap__make_myextendr_wrappers\", use_symbols = ... function call executed rextendr::document(). section @docType package needed generate useDynLib(myextendr, .registration = TRUE) entry NAMESPACE. last section hello_world(). can see roxygen comments copied . Rust function hello_world() arguments R function also arguments. function arguments, generated function wrapper also arguments:","code":"# Generated by extendr: Do not edit by hand # # This file was created with the following call: # .Call(\"wrap__make_myextendr_wrappers\", use_symbols = TRUE, package_name = \"myextendr\") #' @docType package #' @usage NULL #' @useDynLib myextendr, .registration = TRUE NULL #' Return string `\"Hello world!\"` to R. #' @export hello_world <- function() .Call(wrap__hello_world) fn add(x: i32, y: i32) -> i32 { x + y } add <- function(x, y) .Call(wrap__add, x, y)"},{"path":"/dev/articles/package.html","id":"implement-a-new-rust-function","dir":"Articles","previous_headings":"","what":"Implement a new Rust function","title":"Using Rust code in R packages","text":"Now roughly figured extendr works, let’s implement new Rust function. development flow : Modify src/rust/src/lib.rs Run rextendr::document() Run devtools::load_all(\".\") test function exercise, let’s add add(i32, i32) function previous subsection.","code":""},{"path":"/dev/articles/package.html","id":"modify-srcrustsrclib-rs","dir":"Articles","previous_headings":"Implement a new Rust function","what":"1. Modify src/rust/src/lib.rs","title":"Using Rust code in R packages","text":"Add function @export, get exported generated R package. (Without tag, function available internally package programming externally users package.) Don’t forget add function extendr_module!:","code":"/// @export #[extendr] fn add(x: i32, y: i32) -> i32 { x + y } extendr_module! { mod myextendr; fn hello_world; fn add; }"},{"path":"/dev/articles/package.html","id":"run-rextendrdocument","dir":"Articles","previous_headings":"Implement a new Rust function","what":"2. Run rextendr::document()","title":"Using Rust code in R packages","text":"Just run command:","code":"rextendr::document()"},{"path":"/dev/articles/package.html","id":"run-devtoolsload_all--and-test-the-function","dir":"Articles","previous_headings":"Implement a new Rust function","what":"3. Run devtools::load_all(\".\") and test the function","title":"Using Rust code in R packages","text":"Now can load package call add():","code":"devtools::load_all(\".\") add(1L, 2L) #> [1] 3"},{"path":"/dev/articles/rmarkdown.html","id":"evaluating-rust-statements","dir":"Articles","previous_headings":"","what":"Evaluating Rust statements","title":"Using Rust code in R Markdown documents","text":"Chunks type extendr evaluate block Rust statements. value last statement can returned R printed chunk output. example: chunk look knitted document follows: background, extendr knit engine casts Rust integer variable type Result returns value R. Notice lack semicolon (;) end line, indicate want return value. can also write code doesn’t return result R. case, last line end semicolon, example:","code":"```{extendr} rprintln!(\"Hello from Rust!\"); let x = 5; let y = 7; let z = x*y; z ``` rprintln!(\"Hello from Rust!\"); let x = 5; let y = 7; let z = x*y; z ## Hello from Rust! ## [1] 35 let x = 5; let y = 7; let z = x*y; rprintln!(\"{}*{} = {}\", x, y, z); ## 5*7 = 35"},{"path":"/dev/articles/rmarkdown.html","id":"accessing-r-values-from-rust","dir":"Articles","previous_headings":"","what":"Accessing R values from Rust","title":"Using Rust code in R Markdown documents","text":"possible access variables defined R Rust. Let’s define two R variables, numeric string: can read variables Rust using R!() macro. Unfortunately, takes bit error checking type-converting get native Rust values. case things go wrong step. ’re handling errors ?. example, R!() calls R interpreter generate error. even returns value, ’re guaranteed value can coerced real value string. However, as_real() as_str() don’t return errors, return options, need turn None option error via ok_or().","code":"x <- 5.3 y <- \"hello\" let x:f64 = R!(x)? .as_real() .ok_or(\"expected a real\")?; let y:String = R!(y)? .as_str() .ok_or(\"expected a string reference\")? .to_string(); rprintln!(\"The value of x: {}\\nThe value of y: {}\", x, y); ## The value of x: 5.3 ## The value of y: hello"},{"path":"/dev/articles/rmarkdown.html","id":"chaining-chunks-together","dir":"Articles","previous_headings":"","what":"Chaining chunks together","title":"Using Rust code in R Markdown documents","text":"may sometimes want break block Rust code separate Markdown chunks treat one compile unit. can including code one chunk compile unit another, specifying preamble chunk option. option takes character vector chunk names, get included compile unit order provided. Consider example Markdown code: produces following output. Define variable x: Define variable y: Print:","code":"Define variable `x`: ```{extendr chunk_x, eval = FALSE} let x = 1; ``` Define variable `y`: ```{extendr chunk_y, eval = FALSE} let y = 2; ``` Print: ```{extendr out, preamble = c(\"chunk_x\", \"chunk_y\")} rprintln!(\"x = {}, y = {}\", x, y); ``` let x = 1; let y = 2; rprintln!(\"x = {}, y = {}\", x, y); ## x = 1, y = 2"},{"path":"/dev/articles/rmarkdown.html","id":"exporting-rust-functions-or-objects-to-r","dir":"Articles","previous_headings":"","what":"Exporting Rust functions or objects to R","title":"Using Rust code in R Markdown documents","text":"chunk type extendrsrc compiles Rust functions objects registers R called later. example, consider code chunk. creates R functions hello() foo(), well class called Counter. output chunk creates Rust source code: However, now can call functions hello() foo() R use Counter object: code requires external crates, can set dependencies via engine.opts chunk option, like : , Rust code chunk just outputs source: generated functions can used R:","code":"```{extendrsrc} #[extendr] fn hello() -> &'static str { \"Hello from Rust!\" } #[extendr] fn foo(a: &str, b: i64) { rprintln!(\"Data sent to Rust: {}, {}\", a, b); } struct Counter { n: i32, } #[extendr] impl Counter { fn new() -> Self { Self { n: 0 } } fn increment(&mut self) { self.n += 1; } fn get(&self) -> i32 { self.n } } ``` #[extendr] fn hello() -> &'static str { \"Hello from Rust!\" } #[extendr] fn foo(a: &str, b: i64) { rprintln!(\"Data sent to Rust: {}, {}\", a, b); } struct Counter { n: i32, } #[extendr] impl Counter { fn new() -> Self { Self { n: 0 } } fn increment(&mut self) { self.n += 1; } fn get(&self) -> i32 { self.n } } out <- hello() out ## [1] \"Hello from Rust!\" foo(out, nchar(out)) ## Data sent to Rust: Hello from Rust!, 16 x <- Counter$new() x$get() ## [1] 0 x$increment() x$increment() x$get() ## [1] 2 ```{extendrsrc engine.opts = list(dependencies = list(`pulldown-cmark` = \"0.8\"))} 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 } ``` 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 } md_text <- \"# The story of the fox The quick brown fox **jumps over** the lazy dog. The quick *brown fox* jumps over the lazy dog.\" md_to_html(md_text) ## [1] \"

    The story of the fox<\/h1>\\n

    The quick brown fox jumps over<\/strong> the lazy dog.\\nThe quick brown fox<\/em> jumps over the lazy dog.<\/p>\\n\""},{"path":"/dev/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Claus O. Wilke. Author. Andy Thomason. Author. Mossa M. Reimert. Author. Ilia Kosenkov. Author, maintainer. Malcolm Barrett. Author. Josiah Parry. Contributor.","code":""},{"path":"/dev/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"Wilke C, Thomason , Reimert M, Kosenkov , Barrett M (2024). rextendr: Call Rust Code R using 'extendr' Crate. R package version 0.3.1.9000, https://extendr.github.io/rextendr/.","code":"@Manual{, title = {rextendr: Call Rust Code from R using the 'extendr' Crate}, author = {Claus O. Wilke and Andy Thomason and Mossa M. Reimert and Ilia Kosenkov and Malcolm Barrett}, year = {2024}, note = {R package version 0.3.1.9000}, url = {https://extendr.github.io/rextendr/}, }"},{"path":[]},{"path":"/dev/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Call Rust Code from R using the extendr Crate","text":"install release version CRAN, run: use remotes can also install rextendr r-universe: Latest development version can installed GitHub: execute Rust code, also need set working Rust toolchain. See installation instructions libR-sys help. can successfully build libR-sys ’re good.","code":"install.packages(\"rextendr\") remotes::install_cran(\"rextendr\") install.packages('rextendr', repos = c('https://extendr.r-universe.dev', 'https://cloud.r-project.org')) remotes::install_github(\"extendr/rextendr\")"},{"path":[]},{"path":"/dev/index.html","id":"sitrep","dir":"","previous_headings":"Usage","what":"Sitrep","title":"Call Rust Code from R using the extendr Crate","text":"good first step check status Rust toolchain available targets using rust_sitrep(). everything OK, see something like : , instance, toolchain found, see something like : Finally, missing required target (platforms Windows rextendr uses default target), report resemble following:","code":"rust_sitrep() # Rust infrastructure sitrep: # ✔ \"rustup\": 1.26.0 (5af9b9484 2023-04-05) # ✔ \"cargo\": 1.72.0 (103a7ff2e 2023-08-15) # ℹ host: x86_64-pc-windows-msvc # ℹ toolchain: stable-x86_64-pc-windows-msvc (default) # ℹ target: x86_64-pc-windows-gnu rust_sitrep() # Rust infrastructure sitrep: # ✔ \"rustup\": 1.26.0 (5af9b9484 2023-04-05) # ✔ \"cargo\": 1.72.0 (103a7ff2e 2023-08-15) # ℹ host: x86_64-pc-windows-msvc # ! Toolchain stable-x86_64-pc-windows-msvc is required to be installed and set as default # ℹ Run `rustup toolchain install stable-x86_64-pc-windows-msvc` to install it # ℹ Run `rustup default stable-x86_64-pc-windows-msvc` to make it default rust_sitrep() # Rust infrastructure sitrep: # ✔ \"rustup\": 1.26.0 (5af9b9484 2023-04-05) # ✔ \"cargo\": 1.72.0 (103a7ff2e 2023-08-15) # ℹ host: x86_64-pc-windows-msvc # i toolchains: nightly-x86_64-pc-windows-msvc and stable-x86_64-pc-windows-msvc (default) # i targets: x86_64-pc-windows-msvc and i686-pc-windows-msvc # ! Target x86_64-pc-windows-gnu is required on this host machine # i Run `rustup target add x86_64-pc-windows-gnu` to install it"},{"path":"/dev/index.html","id":"code-examples","dir":"","previous_headings":"Usage","what":"Code examples","title":"Call Rust Code from R using the extendr Crate","text":"Basic use example: Something sophisticated: package also enables new chunk type knitr, extendr, compiles evaluates Rust code. example, code chunk one: create following output knitted document:","code":"library(rextendr) # create a Rust function rust_function(\"fn add(a:f64, b:f64) -> f64 { a + b }\") # call it from R add(2.5, 4.7) #> [1] 7.2 library(rextendr) # Rust function that computes a sum of integer or double vectors, preserving the type rust_function( \"fn get_sum(x : Either) -> Either { match x { Either::Left(x) => Either::Left(x.iter().sum()), Either::Right(x) => Either::Right(x.iter().sum()), } }\", use_dev_extendr = TRUE, # Use development version of extendr from GitHub features = \"either\", # Enable support for Either crate ) x <- 1:5 y <- c(1, 2, 3, 4, 5) tibble::tibble( Name = c(\"x\", \"y\"), Data = list(x, y), Types = purrr::map_chr(Data, typeof), Sum = purrr::map(Data, get_sum), SumRaw = purrr::flatten_dbl(Sum), ResultType = purrr::map_chr(Sum, typeof) ) #> # A tibble: 2 × 6 #> Name Data Types Sum SumRaw ResultType #> #> 1 x integer 15 integer #> 2 y double 15 double ```{extendr} rprintln!(\"Hello from Rust!\"); let x = 5; let y = 7; let z = x*y; z ``` rprintln!(\"Hello from Rust!\"); let x = 5; let y = 7; let z = x*y; z #> Hello from Rust! #> [1] 35"},{"path":"/dev/index.html","id":"see-also","dir":"","previous_headings":"","what":"See also","title":"Call Rust Code from R using the extendr Crate","text":"cargo-framework associated R package cargo r-rust organization Please note project released Contributor Code Conduct. participating project agree abide terms.","code":""},{"path":"/dev/principles.html","id":null,"dir":"","previous_headings":"","what":"rextendr design prinicples","title":"rextendr design prinicples","text":"guide documents important internal coding conventions used rextendr.","code":""},{"path":"/dev/principles.html","id":"communicating-with-the-user","dir":"","previous_headings":"","what":"Communicating with the user","title":"rextendr design prinicples","text":"rextendr uses cli package format messages user, generally routed rlang::inform(). UI happen ui_*() functions: {cli} supports glue-based interpolation inline text formatting.","code":""},{"path":"/dev/principles.html","id":"throwing-and-testing-errors","dir":"","previous_headings":"","what":"Throwing and testing errors","title":"rextendr design prinicples","text":"Pass errors via cli::cli_abort(). Ensure class rextendr_error specified. can also add details providing named vector. See ?cli::cli_abort() ?cli::cli_bulelts() message argument.","code":"cli::cli_abort( c( \"Unable to register the extendr module.\", \"x\" = \"Could not find file {.file src/entrypoint.c}.\", \"*\" = \"Are you sure this package is using extendr Rust code?\" ), class = \"rextendr_error\" )"},{"path":"/dev/principles.html","id":"silencing-messages","dir":"","previous_headings":"","what":"Silencing messages","title":"rextendr design prinicples","text":"cli used verbosely inform user. user able optionally silence functions particularly verbose output setting quiet argument TRUE—see ?rust_source example. Silencing cli output done helper local_quiet_cli(quiet). quiet = TRUE , cli output suppressed.","code":""},{"path":"/dev/reference/clean.html","id":null,"dir":"Reference","previous_headings":"","what":"Clean Rust binaries and package cache. — clean","title":"Clean Rust binaries and package cache. — clean","text":"Removes Rust binaries (.dll/.libraries), C wrapper object files, invokes cargo clean reset cargo target directory (found default pkg_root/src/rust/target/). Useful Rust code recompiled scratch.","code":""},{"path":"/dev/reference/clean.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Clean Rust binaries and package cache. — clean","text":"","code":"clean(path = \".\")"},{"path":"/dev/reference/clean.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Clean Rust binaries and package cache. — clean","text":"path [ string ] Path package root.","code":""},{"path":"/dev/reference/cran.html","id":null,"dir":"Reference","previous_headings":"","what":"Use CRAN compliant defaults — cran","title":"Use CRAN compliant defaults — cran","text":"Modifies extendr package use CRAN compliant settings.","code":""},{"path":"/dev/reference/cran.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Use CRAN compliant defaults — cran","text":"","code":"use_cran_defaults(path = \".\", quiet = FALSE, overwrite = NULL, lib_name = NULL) vendor_pkgs(path = \".\", quiet = FALSE, overwrite = NULL)"},{"path":"/dev/reference/cran.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Use CRAN compliant defaults — cran","text":"path File path package generate wrapper code. quiet Logical indicating whether progress messages generated . overwrite Logical scalar NULL indicating whether files path overwritten. NULL (default), function ask user whether file overwritten interactive session nothing non-interactive session. FALSE file already exists, function nothing. TRUE, files overwritten. lib_name String used name Rust library. NULL, sanitized R package name used instead.","code":""},{"path":"/dev/reference/cran.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Use CRAN compliant defaults — cran","text":"vendor_pkgs() returns data.frame two columns crate version use_cran_defaults() returns NULL used solely side effects","code":""},{"path":"/dev/reference/cran.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Use CRAN compliant defaults — cran","text":"use_cran_defaults() modifies existing package provide CRAN complaint settings files. creates configure configure.win files well modifies Makevars Makevars.win use required CRAN settings. vendor_pkgs() used package dependencies required CRAN. executes cargo vendor behalf creating vendor/ directory compressed vendor.tar.xz shipped package . modified dependencies, need need repackage","code":""},{"path":"/dev/reference/cran.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Use CRAN compliant defaults — cran","text":"","code":"if (interactive()) { use_cran_defaults() vendor_pkgs() }"},{"path":"/dev/reference/document.html","id":null,"dir":"Reference","previous_headings":"","what":"Compile Rust code and generate package documentation. — document","title":"Compile Rust code and generate package documentation. — document","text":"function rextendr::document() updates package documentation R package uses extendr code, taking account changes made Rust code. wrapper devtools::document(), executes extendr-specific routines calling devtools::document(). Specifically, ensures Rust code recompiled (necessary) --date R wrappers generated regenerating package documentation.","code":""},{"path":"/dev/reference/document.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compile Rust code and generate package documentation. — document","text":"","code":"document(pkg = \".\", quiet = FALSE, roclets = NULL)"},{"path":"/dev/reference/document.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compile Rust code and generate package documentation. — document","text":"pkg package use, can file path package package object. See .package() information. quiet TRUE suppresses output function. roclets Character vector roclet names use package. default, NULL, uses roxygen roclets option, defaults c(\"collate\", \"namespace\", \"rd\").","code":""},{"path":"/dev/reference/document.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compile Rust code and generate package documentation. — document","text":"return value, called side effects.","code":""},{"path":"/dev/reference/eng_extendr.html","id":null,"dir":"Reference","previous_headings":"","what":"Knitr engines — eng_extendr","title":"Knitr engines — eng_extendr","text":"Two knitr engines enable code chunks type extendr (individual Rust statements evaluated via rust_eval()) extendrsrc (Rust functions classes exported R via rust_source()).","code":""},{"path":"/dev/reference/eng_extendr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Knitr engines — eng_extendr","text":"","code":"eng_extendr(options) eng_extendrsrc(options)"},{"path":"/dev/reference/eng_extendr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Knitr engines — eng_extendr","text":"options list chunk options.","code":""},{"path":"/dev/reference/eng_extendr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Knitr engines — eng_extendr","text":"character string representing engine output.","code":""},{"path":"/dev/reference/inf_dev_extendr_used.html","id":null,"dir":"Reference","previous_headings":"","what":"Inform the user that a development version of extendr is being used. — inf_dev_extendr_used","title":"Inform the user that a development version of extendr is being used. — inf_dev_extendr_used","text":"function returns string used inside cli function. See validate_extendr_features() example.","code":""},{"path":"/dev/reference/inf_dev_extendr_used.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Inform the user that a development version of extendr is being used. — inf_dev_extendr_used","text":"","code":"inf_dev_extendr_used()"},{"path":"/dev/reference/local_quiet_cli.html","id":null,"dir":"Reference","previous_headings":"","what":"Silence {cli} output — local_quiet_cli","title":"Silence {cli} output — local_quiet_cli","text":"Use functions use cli output optionally suppressed.","code":""},{"path":"/dev/reference/local_quiet_cli.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Silence {cli} output — local_quiet_cli","text":"","code":"local_quiet_cli(quiet, env = rlang::caller_env())"},{"path":"/dev/reference/local_quiet_cli.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Silence {cli} output — local_quiet_cli","text":"","code":"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) }"},{"path":"/dev/reference/make_module_macro.html","id":null,"dir":"Reference","previous_headings":"","what":"Generate extendr module macro for Rust source — make_module_macro","title":"Generate extendr module macro for Rust source — make_module_macro","text":"Read Rust source code, find functions implementations #[extendr] attribute, generate extendr_module! macro statement.","code":""},{"path":"/dev/reference/make_module_macro.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generate extendr module macro for Rust source — make_module_macro","text":"","code":"make_module_macro(code, module_name = \"rextendr\")"},{"path":"/dev/reference/make_module_macro.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generate extendr module macro for Rust source — make_module_macro","text":"code Character vector containing Rust code. module_name Module name","code":""},{"path":"/dev/reference/make_module_macro.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Generate extendr module macro for Rust source — make_module_macro","text":"Character vector holding contents generated macro statement.","code":""},{"path":"/dev/reference/make_module_macro.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Generate extendr module macro for Rust source — make_module_macro","text":"function uses simple regular expressions Rust parsing can get confused valid Rust code. meant convenience simple use cases. particular, currently handle implementations generics.","code":""},{"path":"/dev/reference/register_extendr.html","id":null,"dir":"Reference","previous_headings":"","what":"Register the extendr module of a package with R — register_extendr","title":"Register the extendr module of a package with R — register_extendr","text":"function generates wrapper code corresponding extendr module R package. useful package development, generally want appropriate R code wrapping Rust functions implemented via extendr. development settings, want call function directly, instead call rextendr::document().","code":""},{"path":"/dev/reference/register_extendr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Register the extendr module of a package with R — register_extendr","text":"","code":"register_extendr(path = \".\", quiet = FALSE, force = FALSE, compile = NA)"},{"path":"/dev/reference/register_extendr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Register the extendr module of a package with R — register_extendr","text":"path Path package root looked . quiet Logical indicating whether progress messages generated . force Logical indicating whether force regenerating R/extendr-wrappers.R even seem need updated. (default, generation skipped newer DLL). compile Logical indicating whether recompile DLLs: TRUE always recompiles NA recompiles needed (.e., source files manifest file newer DLL) FALSE never recompiles","code":""},{"path":"/dev/reference/register_extendr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Register the extendr module of a package with R — register_extendr","text":"(Invisibly) Path file containing generated wrappers.","code":""},{"path":"/dev/reference/register_extendr.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Register the extendr module of a package with R — register_extendr","text":"function register_extendr() compiles package Rust code required, wrapper code retrieved compiled Rust code saved R/extendr-wrappers.R. Afterwards, re-document re-install package wrapper functions take effect.","code":""},{"path":[]},{"path":"/dev/reference/rextendr.html","id":null,"dir":"Reference","previous_headings":"","what":"Call Rust code from R using the 'extendr' Crate — rextendr","title":"Call Rust code from R using the 'extendr' Crate — rextendr","text":"rextendr package implements functions interface Rust code R. See rust_source() details.","code":""},{"path":[]},{"path":"/dev/reference/rextendr.html","id":"author","dir":"Reference","previous_headings":"","what":"Author","title":"Call Rust code from R using the 'extendr' Crate — rextendr","text":"Maintainer: Ilia Kosenkov ilia.kosenkov@outlook.com (ORCID) Authors: Claus O. Wilke wilke@austin.utexas.edu (ORCID) Andy Thomason andy@andythomason.com Mossa M. Reimert mossa@sund.ku.dk Malcolm Barrett malcolmbarrett@gmail.com (ORCID) contributors: Josiah Parry (ORCID) [contributor]","code":""},{"path":"/dev/reference/rust_eval.html","id":null,"dir":"Reference","previous_headings":"","what":"Evaluate Rust code — rust_eval","title":"Evaluate Rust code — rust_eval","text":"Compile evaluate one Rust expressions. last expression Rust code returns value (.e., end ;), value returned R. value returned need type Robj, long can cast type .(). conversion done automatically, worry code.","code":""},{"path":"/dev/reference/rust_eval.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Evaluate Rust code — rust_eval","text":"","code":"rust_eval(code, env = parent.frame(), ...)"},{"path":"/dev/reference/rust_eval.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Evaluate Rust code — rust_eval","text":"code Input rust code. env R environment Rust code evaluated. ... parameters handed rust_function().","code":""},{"path":"/dev/reference/rust_eval.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Evaluate Rust code — rust_eval","text":"return value generated Rust code.","code":""},{"path":"/dev/reference/rust_eval.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Evaluate Rust code — rust_eval","text":"","code":"if (FALSE) { # \\dontrun{ # Rust code without return value, called only for its side effects rust_eval( code = 'rprintln!(\"hello from Rust!\");' ) # Rust code with return value rust_eval( code = \" let x = 5; let y = 7; let z = x * y; z // return to R; rust_eval() takes care of type conversion code \" ) } # }"},{"path":"/dev/reference/rust_sitrep.html","id":null,"dir":"Reference","previous_headings":"","what":"Report on Rust infrastructure — rust_sitrep","title":"Report on Rust infrastructure — rust_sitrep","text":"Prints detailed report state Rust infrastructure host machine.","code":""},{"path":"/dev/reference/rust_sitrep.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Report on Rust infrastructure — rust_sitrep","text":"","code":"rust_sitrep()"},{"path":"/dev/reference/rust_sitrep.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Report on Rust infrastructure — rust_sitrep","text":"Nothing","code":""},{"path":"/dev/reference/rust_source.html","id":null,"dir":"Reference","previous_headings":"","what":"Compile Rust code and call from R — rust_source","title":"Compile Rust code and call from R — rust_source","text":"rust_source() compiles loads single Rust file use R. rust_function() compiles loads single Rust function use R.","code":""},{"path":"/dev/reference/rust_source.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compile Rust code and call from R — rust_source","text":"","code":"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, ... )"},{"path":"/dev/reference/rust_source.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compile Rust code and call from R — rust_source","text":"file Input rust file source. code Input rust code, used instead file. module_name Name module defined Rust source via extendr_module!. Default \"rextendr\". generate_module_macro FALSE file specified, match exactly name module defined source. dependencies Character vector dependencies lines added Cargo.toml file. patch.crates_io Character vector patch statements crates.io added Cargo.toml file. profile Rust profile. Can either \"dev\", \"release\" \"perf\". default, \"dev\", compiles faster produces slower code. toolchain Rust toolchain. default, NULL, compiles system default toolchain. Accepts valid Rust toolchain qualifiers, \"nightly\", (Windows) \"stable-msvc\". extendr_deps Versions extendr-* crates. Defaults rextendr.extendr_deps option (list(`extendr-api` = \"*\")) use_dev_extendr TRUE, otherwise, uses rextendr.extendr_dev_deps option (list(`extendr-api` = list(git = \"https://github.com/extendr/extendr\")). features vector extendr-api features enabled. Supported values \"ndarray\", \"num-complex\", \"serde\", \"graphics\". Unknown features produce warning quiet TRUE. env R environment wrapping functions defined. use_extendr_api Logical indicating whether use extendr_api::prelude::*; added top Rust source provided via code. Default TRUE. Ignored Rust source provided via file. generate_module_macro Logical indicating whether Rust module macro automatically generated code. Default TRUE. Ignored Rust source provided via file. macro generation done make_module_macro() may fail complex cases. something work, try calling make_module_macro() code see whether generated macro code issues. cache_build Logical indicating whether builds cached calls rust_source(). quiet Logical indicating whether compile output generated . use_rtools Logical indicating whether append path Rtools PATH variable Windows using RTOOLS40_HOME environment variable (set). appended path depends process architecture. nothing platforms. use_dev_extendr Logical indicating whether use development version extendr. effect extendr_deps set. extendr_fn_options list extendr function options inserted #[extendr(...)] attribute ... parameters handed rust_source().","code":""},{"path":"/dev/reference/rust_source.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compile Rust code and call from R — rust_source","text":"result dyn.load(), object class DLLInfo. See getLoadedDLLs() details.","code":""},{"path":"/dev/reference/rust_source.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compile Rust code and call from R — rust_source","text":"","code":"if (FALSE) { # \\dontrun{ # creating a single rust function rust_function(\"fn add(a:f64, b:f64) -> f64 { a + b }\") add(2.5, 4.7) # creating multiple rust functions at once code <- 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 fox The quick brown fox **jumps over** the lazy dog. The quick *brown fox* jumps over the lazy dog.\" md_to_html(md_text) } # }"},{"path":"/dev/reference/to_toml.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert R list() into toml-compatible format. — to_toml","title":"Convert R list() into toml-compatible format. — to_toml","text":"to_toml() can used build Cargo.toml. cargo manifest can represented terms R objects, allowing limited validation syntax verification. function converts manifests written using R objects toml representation, applying basic formatting, ideal generating cargo manifests runtime.","code":""},{"path":"/dev/reference/to_toml.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert R list() into toml-compatible format. — to_toml","text":"","code":"to_toml(..., .str_as_literal = TRUE, .format_int = \"%d\", .format_dbl = \"%g\")"},{"path":"/dev/reference/to_toml.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert R list() into toml-compatible format. — to_toml","text":"... list toml constructed. Supports nesting tidy evaluation. .str_as_literal Logical indicating whether treat strings literal (single quotes escapes) basic (escaping sequences) ones. Default TRUE. .format_int, .format_dbl Character scalar describing number formatting. Compatible sprintf.","code":""},{"path":"/dev/reference/to_toml.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert R list() into toml-compatible format. — to_toml","text":"character vector, element corresponds one line resulting output.","code":""},{"path":"/dev/reference/to_toml.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Convert R list() into toml-compatible format. — to_toml","text":"","code":"# Produces [workspace] with no children to_toml(workspace = NULL) #> [workspace] to_toml(patch.crates_io = list(`extendr-api` = list(git = \"git-ref\"))) #> [patch.crates_io] #> extendr-api = { git = 'git-ref' } # Single-element arrays are distinguished from scalars # using explicitly set `dim` to_toml(lib = list(`crate-type` = array(\"cdylib\", 1))) #> [lib] #> crate-type = [ 'cdylib' ]"},{"path":"/dev/reference/use_extendr.html","id":null,"dir":"Reference","previous_headings":"","what":"Set up a package for use with Rust extendr code — use_extendr","title":"Set up a package for use with Rust extendr code — use_extendr","text":"Create scaffolding needed add Rust extendr code R package. use_extendr() adds small Rust library single Rust function returns string \"Hello world!\". also adds wrapper code Rust function can called R hello_world().","code":""},{"path":"/dev/reference/use_extendr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Set up a package for use with Rust extendr code — use_extendr","text":"","code":"use_extendr( path = \".\", crate_name = NULL, lib_name = NULL, quiet = FALSE, overwrite = NULL, edition = c(\"2021\", \"2018\") )"},{"path":"/dev/reference/use_extendr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Set up a package for use with Rust extendr code — use_extendr","text":"path File path package generate wrapper code. crate_name String used name Rust crate. NULL, sanitized R package name used instead. lib_name String used name Rust library. NULL, sanitized R package name used instead. quiet Logical indicating whether progress messages generated . overwrite Logical scalar NULL indicating whether files path overwritten. NULL (default), function ask user whether file overwritten interactive session nothing non-interactive session. FALSE file already exists, function nothing. TRUE, files overwritten. edition String indicating Rust edition used; Default \"2021\".","code":""},{"path":"/dev/reference/use_extendr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Set up a package for use with Rust extendr code — use_extendr","text":"logical value (invisible) indicating whether package files generated .","code":""},{"path":"/dev/reference/write_license_note.html","id":null,"dir":"Reference","previous_headings":"","what":"Generate LICENSE.note file. — write_license_note","title":"Generate LICENSE.note file. — write_license_note","text":"LICENSE.note generated function contains information Rust crate dependencies. use function, cargo-lincense command must installed.","code":""},{"path":"/dev/reference/write_license_note.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Generate LICENSE.note file. — write_license_note","text":"","code":"write_license_note(path = \".\", quiet = FALSE, force = TRUE)"},{"path":"/dev/reference/write_license_note.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Generate LICENSE.note file. — write_license_note","text":"path Path package root looked . quiet Logical indicating whether progress messages generated . force Logical indicating whether regenerate LICENSE.note LICENSE.note already exists.","code":""},{"path":"/dev/reference/write_license_note.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Generate LICENSE.note file. — write_license_note","text":"return value, called side effects.","code":""},{"path":"/dev/news/index.html","id":"rextendr-development-version","dir":"Changelog","previous_headings":"","what":"rextendr (development version)","title":"rextendr (development version)","text":"use_extendr() sets DESCRIPTION’s SystemRequirements field according CRAN policy Cargo (Rust's package manager), rustc (#329) Introduces new functions use_cran_defaults() vendor_pkgs() ease publication extendr-powered packages CRAN. See new article CRAN compliant extendr packages use (#320). rust_sitrep() now better communicates status Rust toolchain available targets. also guides user necessary installation steps fix Rust setup (#318). use_extendr() document() now set SystemRequirements field DESCRIPTION file Cargo (rustc package manager) field empty (#298). use_extendr() gets new ability overwrite existing rextendr templates (#292). use_extendr() sets publish = false [package] section Cargo.toml (#297). use_extendr() correctly handles calls path equal \".\" (current folder), active usethis project (#323). Fixes issue pre-defined set known features: added either (#338) create_extendr_package() allows user create project directory using RStudio’s Project Command. (#321) Support RTOOLS44 (#347) Removed use_try_from option rust_function, added use_rng (#354) Added use_crate() function make adding dependencies Cargo.toml easier within R, similar usethis::use_package() (#361)","code":""},{"path":"/dev/news/index.html","id":"rextendr-030","dir":"Changelog","previous_headings":"","what":"rextendr 0.3.0","title":"rextendr 0.3.0","text":"CRAN release: 2023-05-30 Ilia Kosenkov now official maintainer. Josiah Parry now contributor. Support Rtools43 (#231). rextendr migrated use cli raising errors warnings. Developer note: new helper function local_quiet_cli() introduced R/utils.R simplify silencing cli output.","code":""},{"path":"/dev/news/index.html","id":"new-features-0-3-0","dir":"Changelog","previous_headings":"","what":"New features","title":"rextendr 0.3.0","text":"new function rust_sitrep() prints short report currently installed Rust toolchain (#274). new function write_license_note() generate LICENSE.note file Cargo.toml (#271). extendr_fn_options parameter rust_source() controls type options emitted #[extendr()] attribute (#252). use_dev_extendr flag makes rust_source() family functions compile code using development version extendr. Development configuration stored option named rextendr.extendr_dev_deps (#251). features parameter rust_source() now correctly enables features extendr-api references required crates. features available release version extendr raises warning (#249). -win.def file containing DLL exports created rextendr::use_extendr(). used linking phase Windows solves problem compiling large projects, polars (#212) Support extendr macro options (#128). rust_source() got features argument specify Cargo features activate (#140). rextendr::document() now sets envvars devtools::document() sets, e.g. NOT_CRAN (#135).","code":""},{"path":"/dev/news/index.html","id":"rextendr-020","dir":"Changelog","previous_headings":"","what":"rextendr 0.2.0","title":"rextendr 0.2.0","text":"CRAN release: 2021-06-15 First official release.","code":""}]