From da2d2584041de120336237ee6fe0df533060fa57 Mon Sep 17 00:00:00 2001 From: Kenneth Blake Vernon <53311626+kbvernon@users.noreply.github.com> Date: Sat, 29 Jun 2024 09:04:06 -0600 Subject: [PATCH] port to quarto (#14) * port to quarto * add cron and remove pkgdown ga * remove link to css file * reuse mit license * quarto freeze * revert to md * add preview note * small e * temp fix - add logo * start faq and include developer info --- .Rbuildignore | 2 + .github/workflows/pkgdown.yaml | 51 ----- .github/workflows/quarto-publish.yml | 27 +++ .gitignore | 14 ++ CHANGELOG.md | 75 +++--- DESCRIPTION | 33 --- README.md | 20 +- _pkgdown.yml | 42 ---- _quarto.yml | 32 +++ faq.css | 21 ++ faq.qmd | 26 +++ {man/figures => images}/extendr-logo-256.png | Bin {man/figures => images}/sin_plot.png | Bin index.md | 218 ------------------ index.qmd | 229 +++++++++++++++++++ pkgdown/templates/navbar.html | 32 --- started.md => started.qmd | 4 +- 17 files changed, 396 insertions(+), 430 deletions(-) delete mode 100644 .github/workflows/pkgdown.yaml create mode 100644 .github/workflows/quarto-publish.yml delete mode 100644 DESCRIPTION delete mode 100644 _pkgdown.yml create mode 100644 _quarto.yml create mode 100644 faq.css create mode 100644 faq.qmd rename {man/figures => images}/extendr-logo-256.png (100%) rename {man/figures => images}/sin_plot.png (100%) delete mode 100644 index.md create mode 100644 index.qmd delete mode 100644 pkgdown/templates/navbar.html rename started.md => started.qmd (95%) diff --git a/.Rbuildignore b/.Rbuildignore index b6a77cd..387d267 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,3 +1,5 @@ ^_pkgdown\.yml$ ^docs$ ^pkgdown$ +^.*\.Rproj$ +^\.Rproj\.user$ diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml deleted file mode 100644 index cbaf8a4..0000000 --- a/.github/workflows/pkgdown.yaml +++ /dev/null @@ -1,51 +0,0 @@ -on: - push: - branches: - - main - -name: pkgdown - -jobs: - pkgdown: - runs-on: ubuntu-20.04 - env: - GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - steps: - - uses: actions/checkout@v2 - - - uses: r-lib/actions/setup-r@v1 - - - uses: r-lib/actions/setup-pandoc@v1 - - - name: Install System Deps - run: | - sudo apt-get install libcurl4-openssl-dev libharfbuzz-dev libfribidi-dev libpng-dev libtiff-dev libjpeg-dev - - - name: Query dependencies - run: | - install.packages("remotes") - saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2) - writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version") - shell: Rscript {0} - - - name: Restore R package cache - uses: actions/cache@v2 - with: - path: ${{ env.R_LIBS_USER }} - key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} - restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- - - - name: Install dependencies - run: | - remotes::install_deps(dependencies = TRUE) - remotes::install_github("r-lib/pkgdown@ce9781a") - shell: Rscript {0} - - - name: Install package - run: R CMD INSTALL . - - - name: Deploy package - run: | - git config --local user.email "actions@github.com" - git config --local user.name "GitHub Actions" - Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE, branch="gh-pages")' diff --git a/.github/workflows/quarto-publish.yml b/.github/workflows/quarto-publish.yml new file mode 100644 index 0000000..1cc1530 --- /dev/null +++ b/.github/workflows/quarto-publish.yml @@ -0,0 +1,27 @@ +on: + workflow_dispatch: + push: + branches: main + schedule: + - cron: '0 0 * * 5' # Every Friday at midnight UTC + +name: Quarto Publish + +jobs: + build-deploy: + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Quarto + uses: quarto-dev/quarto-actions/setup@v2 + + - name: Render and Publish + uses: quarto-dev/quarto-actions/publish@v2 + with: + target: gh-pages + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7a78719..39a204d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,16 @@ docs *~ +.Rproj.user +*.Rproj + +/.quarto/ +/_site/ +# rust specific .gitignore +target/ +debug/ +Cargo.lock +**/*.rs.bk +*.pdb +# r specific +.Rproj.user/ +*.Rproj \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ff257f..d7497a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,76 +2,81 @@ ## extendr devel -- Fixed Clippy warnings +- Fixed Clippy warnings -- Fixed "myvar" test failures - related to base_env() being the "local" enviroment in the tests. +- Fixed "myvar" test failures - related to base_env() being the "local" + enviroment in the tests. -- Fixes for builds on ARM and PPC platforms. +- Fixes for builds on ARM and PPC platforms. -- Converted R! to a procedural macro, allowing parameters. +- Converted R! to a procedural macro, allowing parameters. -- Converted pairlist! to a procedural macro. +- Converted pairlist! to a procedural macro. -- Refactor extendr_macros. +- Refactor extendr_macros. -- Remove unused lazy_static +- Remove unused lazy_static -- Continued improvments to wrappers for specific R types such as environments, functions and symbols. +- Continued improvments to wrappers for specific R types such as environments, + functions and symbols. -- Install system dependencies on Linux. +- Install system dependencies on Linux. -- Use Use failure() to trigger steps on failures +- Use Use failure() to trigger steps on failures -- `SymPair::sym_pair()` now returns `(Option, Robj)` +- `SymPair::sym_pair()` now returns `(Option, Robj)` ## extendr 0.2.0 -- Added contributing guidelines and code of conduct. +- Added contributing guidelines and code of conduct. -- Made use of ndarray optional. +- Made use of ndarray optional. -- Made #[extendr] calls panic and thread safe. +- Made #\[extendr\] calls panic and thread safe. -- Added NA handling to the #[extendr] macro. +- Added NA handling to the #\[extendr\] macro. -- Added a separate extendr-engine crate that is needed when calling R from Rust. +- Added a separate extendr-engine crate that is needed when calling R from + Rust. -- Wrapper classes for pairlists, environment, raw, symbols and others. +- Wrapper classes for pairlists, environment, raw, symbols and others. -- More iterator support. +- More iterator support. -- Operators index, slice, dollar, double_colon, +, -, * and /`. +- Operators index, slice, dollar, double_colon, +, -, \* and /\`. -- Debug printing support expanded to use wrappers. +- Debug printing support expanded to use wrappers. -- Conversion of Robj to wrapper types. +- Conversion of Robj to wrapper types. -- Multithreaded support - allows multithreaded testing using a recursive spinlock. +- Multithreaded support - allows multithreaded testing using a recursive + spinlock. -- Bool type extended and implemented using TRUE, FALSE and NA_BOOLEAN. +- Bool type extended and implemented using TRUE, FALSE and NA_BOOLEAN. -- Optional parameters to support NA handing. +- Optional parameters to support NA handing. -- Errors thrown if input parameters without Option are NA. +- Errors thrown if input parameters without Option are NA. -- Harmonising of function names into integer, real, logical, symbol, raw, list, pairlist and env. +- Harmonising of function names into integer, real, logical, symbol, raw, + list, pairlist and env. -- Refactored robj code into several source files. +- Refactored robj code into several source files. -- Many functions updated to use generic types. +- Many functions updated to use generic types. -- R! macro for executing R source code. +- R! macro for executing R source code. -- call! macro to call R code. +- call! macro to call R code. -- sym! macro to generate symbols. +- sym! macro to generate symbols. -- Simplification of vector generation using collect_robj and ToVectorValue. +- Simplification of vector generation using collect_robj and ToVectorValue. -- Added array types `[1, 2, 3]` as `Robj::from` targets. +- Added array types `[1, 2, 3]` as `Robj::from` targets. -- Macros now mostly return errors. +- Macros now mostly return errors. ## extendr 0.1.10 -- Fix build on Windows and MacOS. +- Fix build on Windows and MacOS. diff --git a/DESCRIPTION b/DESCRIPTION deleted file mode 100644 index 666e6d0..0000000 --- a/DESCRIPTION +++ /dev/null @@ -1,33 +0,0 @@ -Package: ExtendrWeb -Title: A safe and user friendly R extension interface using Rust. -Version: 0.4.0 -Authors@R: - c(person(given = "Andy", - family = "Thomason", - role = c("aut", "cre"), - email = "andy@andythomason.com"), - person(given = "Mossa M.", - family = "Reimert", - role = "aut", - email = "mossa@sund.ku.dk"), - person(given = "Claus O.", - family = "Wilke", - role = c("aut"), - email = "wilke@austin.utexas.edu", - comment = c(ORCID = "0000-0002-7470-9261")), - person(given = "Hiroaki", - family = "Yutani", - role = "aut", - email = "yutani.ini@gmail.com", - comment = c(ORCID = "0000-0002-3385-7233")), - person(given = "Ilia", - family = "Kosenkov", - role = "aut", - email = "ilia.kosenkov@outlook.com", - comment = c(ORCID = "0000-0001-5563-7840")), - person(given = "Daniel", - family = "Falbel", - role = "aut"), - person("Genomics Plc", role = c("cph"))) -License: MIT -Encoding: UTF-8 diff --git a/README.md b/README.md index cab25d6..dc4c5a0 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,5 @@ # extendr.github.io -This repository contains a dummy R project which allows us to -build a website for Extendr using `pkgdown`. +Repository for the **extendr** website built using [Quarto](https://quarto.org/). -To build the site locally: - -```r -remotes::install_github("r-lib/pkgdown") -devtools::install() -pkgdown::build_site() -``` - -There is a github action that builds the site and deploys to -the `gh-pages` branch when pushing to `main`. - -On linux, you will also need: - -```shell -sudo apt install fontconfig libfreetype2-dev libfontconfig1-dev libharfbuzz-dev libfribidi-dev pandoc -``` +Website can be previewed using `quarto preview`. \ No newline at end of file diff --git a/_pkgdown.yml b/_pkgdown.yml deleted file mode 100644 index cc529c2..0000000 --- a/_pkgdown.yml +++ /dev/null @@ -1,42 +0,0 @@ -url: https://extendr.github.io/ - -title: Extendr - -home: - title: | - Extendr: A safe and user friendly R extension interface using Rust. - sidebar: - structure: [custom, license, dev, authors] - components: - custom: - title: "" - text: | - Extendr logo - -template: - bootstrap: 4 - -navbar: - title: Extendr - left: - - icon: fa-home fa-lg - href: index.html - - text: "Getting started" - href: started.html - - text: Contributing - href: CONTRIBUTING.html - - text: "News" - href: CHANGELOG.html - - text: "API Docs" - href: https://extendr.github.io/extendr/extendr_api/ - right: - - icon: fa-github - href: https://github.com/extendr/extendr - - icon: fab fa-discord - href: https://discord.gg/7hmApuc - -authors: - sidebar: - roles: [aut, cph] - - diff --git a/_quarto.yml b/_quarto.yml new file mode 100644 index 0000000..f3fdaa7 --- /dev/null +++ b/_quarto.yml @@ -0,0 +1,32 @@ +project: + type: website + +execute: + freeze: true + +website: + title: "extendr" + navbar: + left: + - text: "Getting started" + href: started.qmd + - text: Contributing + href: CONTRIBUTING.md + - text: "News" + href: CHANGELOG.md + - text: "API Docs" + href: https://extendr.github.io/extendr/extendr_api/ + - text: "FAQ" + href: faq.qmd + right: + - icon: github + href: https://github.com/extendr/extendr + - icon: discord + href: https://discord.gg/7hmApuc + +format: + html: + theme: + light: flatly + dark: darkly + toc: false diff --git a/faq.css b/faq.css new file mode 100644 index 0000000..529cdc9 --- /dev/null +++ b/faq.css @@ -0,0 +1,21 @@ + +#TOC ul { + padding-left: 1rem; +} + +#TOC ul li { + padding-bottom: 0.5rem; +} + +#TOC ul li a { + text-decoration: none; +} + +#toc-title, +.toc-actions { + display: none; +} + +.comparison ul { + padding-left: 1.1em; +} \ No newline at end of file diff --git a/faq.qmd b/faq.qmd new file mode 100644 index 0000000..e527774 --- /dev/null +++ b/faq.qmd @@ -0,0 +1,26 @@ +--- +title: "Frequently Asked Questions" +toc: true +toc-location: body +css: faq.css +--- + +### What can I use extendr for? + +### How do I install extendr? + +### Who are the developers of extendr? + +Authors and maintainers include: + +- Amy Thomason (author and creator, + [\@andy-thomason](https://github.com/andy-thomason)) +- Mossa M. Reimert (author and maintainer, + [\@CGMossa](https://github.com/CGMossa)) +- Claus O. Wilke (author, [\@clauswilke](https://github.com/clauswilke)) +- Horoaki Yutani (author, + [\@yutannihilation](https://github.com/yutannihilation)) +- Ilia Kosenkov (author and maintainer, + [\@Ilia-Kosenkov](https://github.com/Ilia-Kosenkov)) +- Daniel Falbel (author, [\@dfalbel](https://github.com/dfalbel)) +- Josiah Parry (maintainer, [\@JosiahParry](https://github.com/JosiahParry)) diff --git a/man/figures/extendr-logo-256.png b/images/extendr-logo-256.png similarity index 100% rename from man/figures/extendr-logo-256.png rename to images/extendr-logo-256.png diff --git a/man/figures/sin_plot.png b/images/sin_plot.png similarity index 100% rename from man/figures/sin_plot.png rename to images/sin_plot.png diff --git a/index.md b/index.md deleted file mode 100644 index 1455223..0000000 --- a/index.md +++ /dev/null @@ -1,218 +0,0 @@ -# extendr - A safe and user friendly R extension interface using Rust - -[![Github Actions Build Status](https://github.com/extendr/extendr/workflows/Tests/badge.svg)](https://github.com/extendr/extendr/actions) -[![Crates.io](https://img.shields.io/crates/v/extendr-api.svg)](https://crates.io/crates/extendr-api) -[![Documentation](https://docs.rs/extendr-api/badge.svg)](https://docs.rs/extendr-api) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) - -Extendr is a Rust extension mechanism for R - -The following code illustrates a simple structure trait -which is written in Rust. The data is defined in the `struct` -declaration and the methods in the `impl`. - -Extendr consists of the following projects: - -* [`extendr`](https://extendr.github.io/extendr) set of crates, including: - * [`extendr-api`](https://extendr.github.io/extendr/extendr_api) - the core Extendr crate providing all of the functionality; - * [`extendr-macros`](https://extendr.github.io/extendr/extendr_macros) - Extendr crate responsbile for Rust wrapper generation; - * [`extendr-engine`](https://extendr.github.io/extendr/extendr_engine) - crate that enables launching R sessions from Rust code; -* [`rextendr`](https://extendr.github.io/rextendr) - an R package that helps scaffolding extendr-enabled packages or compiling Rust code dynamically; -* [`libR-sys`](https://extendr.github.io/libR-sys/libR_sys) - provides auto-generated R bindings for Rust. - -```rust -use extendr_api::prelude::*; - -struct Person { - pub name: String, -} - -#[extendr] -impl Person { - fn new() -> Self { - Self { name: "".to_string() } - } - - fn set_name(&mut self, name: &str) { - self.name = name.to_string(); - } - - fn name(&self) -> &str { - self.name.as_str() - } -} - -#[extendr] -fn aux_func() { -} - - -// Macro to generate exports -extendr_module! { - mod classes; - impl Person; - fn aux_func; -} -``` - -The `#[extendr]` attribute causes the compiler to generate -wrapper and registration functions for R which are called -when the package is loaded. - -On R's side, users can access to the above Rust functions as follows: - -``` r -# call function -aux_func() - -# create Person object -p <- Person$new() -p$set_name("foo") -p$name() # "foo" is returned -``` - -The `extendr_module!` macro lists the module name and exported functions -and interfaces. - -This library aims to provide an interface that will be familiar to -first-time users of Rust or indeed any compiled language. - -Anyone who knows the R library should be able to write R extensions. - -## Wrappers for R types - -Extendr provides a number of wrappers for R types. These fall into -three categories, scalar types such as a single integer, vector -types which are an array of a scalar type and linked list -types used to represent R code and call arguments. - -### Scalar types - -R type|Extendr wrapper|Deref type: `&*object` -------|---------------|---------------------- -`Any`|`extendr_api::robj::Robj`|N/A -`character`|`extendr_api::wrapper::Rstr`|N/A -`integer`|`extendr_api::wrapper::Rint`|N/A -`double`|`extendr_api::wrapper::Rfloat`|N/A -`complex`|`extendr_api::wrapper::Rcplx`|N/A -`extptr`|`extendr_api::wrapper::ExternalPtr`|`&T` / `&mut T` - -### Vector types - -R type|Extendr wrapper|Deref type: `&*object` -------|---------------|---------------------- -`integer`|`extendr_api::wrapper::Integers`|`&[Rint]` -`double`|`extendr_api::wrapper::Doubles`|`&[Rfloat]` -`logical`|`extendr_api::wrapper::Logicals`|`&[Rbool]` -`complex`|`extendr_api::wrapper::Complexes`|`&[Rcplx]` -`string`|`extendr_api::wrapper::Strings`|`&[Rstr]` -`list`|`extendr_api::wrapper::List`|`&[Robj]` -`data.frame`|`extendr_api::wrapper::Dataframe`|`&[Robj]` -`expression`|`extendr_api::wrapper::Expression`|`&[Lang]` - -### Linked list types - -R type|Extendr wrapper|Deref type: `&*object` -------|---------------|---------------------- -`pairlist`|`extendr_api::wrapper::Pairlist`|N/A -`lang`|`extendr_api::wrapper::Lang`|N/A - -## Examples - -### Returning lists and strings - -Lists and strings in rust are vectors of R objects. -These are represented by the wrappers `List` and `Strings`. - -`List` contains a slice of `Robj` wrappers which can contain -any R object. - -`Strings` contains a slice of `Rstr` wrappers which can -contain a single string. - -These examples show how to return a list or string to -R from Rust. - -```rust -use extendr_api::wrapper::{List, Strings}; -use extendr_api::list; - -fn get_strings() -> Strings { - Strings::from_values( - (0..10) - .map(|i| format!("number {}", i)) - ) -} - -fn get_named_list() -> List { - list!(x=1, y="xyz", z=()) -} - -fn get_unnamed_list() -> List { - List::from_values(0..10) -} -``` - -### Returning scalars - -Whilst we can use `i32` and `f64` in Extendr to return values. -A better way is to use the `Rint` and `Rfloat` wrappers which -provide access to the `NA` value used by R to represent missing -data. - -```rust -use extendr_api::scalar::{Rint, Rfloat}; - -// for .na() -use extendr_api::CanBeNA; - -fn get_int() -> Rint { - Rint::from(1) -} - -fn get_na_int() -> Rint { - Rint::na() -} - -fn get_float() -> Rfloat { - Rfloat::from(1.0) -} - -fn get_na_float() -> Rfloat { - Rfloat::na() -} -``` - -### Plotting a PNG file from Rust - -We can use Extendr to take advantage of the stats and plotting functions -in R. - -For example, we could make a web server that returns plots of incoming data. - -```rust -use extendr_api::{test, Result, eval_string, eval_string_with_params}; -use extendr_api::{Doubles, R}; - -fn main() { - test!{ - let x = Doubles::from_values((0..100).map(|i| i as f64 / 20.0)); - - // let y = Doubles::from_values(x.iter().map(|x| x.inner().sin())); - let y = Doubles::from_values((0..100).map(|i| (i as f64 / 20.0).sin())); - - // Set a PNG device - R!(r#"png("/tmp/sin_plot.png")"#)?; - - // Plot x and y - R!("plot({{&x}}, {{&y}})")?; - - // Linear model. - R!("abline(lm({{y}} ~ {{x}}))")?; - - // Flush the device to the image. - R!("dev.off()")?; - } -} - -``` diff --git a/index.qmd b/index.qmd new file mode 100644 index 0000000..bf8d693 --- /dev/null +++ b/index.qmd @@ -0,0 +1,229 @@ +--- +title: "" +--- + +:::::: {style="margin:0; width: 100%;"} +::: {style="margin:0; width: 81%; float: left;"} +## extendr - A safe and user friendly R extension interface using Rust +::: +::: {style="margin: 0.25rem 0 0 0; width: 19%; float: right;"} +![](images/extendr-logo-256.png){width="100%" fig-alt="rextendr logo"} +::: +:::::: + +[![Github Actions Build +Status](https://github.com/extendr/extendr/workflows/Tests/badge.svg)](https://github.com/extendr/extendr/actions) +[![Crates.io](https://img.shields.io/crates/v/extendr-api.svg)](https://crates.io/crates/extendr-api) +[![Documentation](https://docs.rs/extendr-api/badge.svg)](https://docs.rs/extendr-api) +[![License: +MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +Extendr is a Rust extension mechanism for R + +The following code illustrates a simple structure trait which is written in +Rust. The data is defined in the `struct` declaration and the methods in the +`impl`. + +Extendr consists of the following projects: + +- [`extendr`](https://extendr.github.io/extendr) set of crates, including: + - [`extendr-api`](https://extendr.github.io/extendr/extendr_api) - the + core Extendr crate providing all of the functionality; + - [`extendr-macros`](https://extendr.github.io/extendr/extendr_macros) - + Extendr crate responsbile for Rust wrapper generation; + - [`extendr-engine`](https://extendr.github.io/extendr/extendr_engine) - + crate that enables launching R sessions from Rust code; +- [`rextendr`](https://extendr.github.io/rextendr) - an R package that helps + scaffolding extendr-enabled packages or compiling Rust code dynamically; +- [`libR-sys`](https://extendr.github.io/libR-sys/libR_sys) - provides + auto-generated R bindings for Rust. + +``` rust +use extendr_api::prelude::*; + +struct Person { + pub name: String, +} + +#[extendr] +impl Person { + fn new() -> Self { + Self { name: "".to_string() } + } + + fn set_name(&mut self, name: &str) { + self.name = name.to_string(); + } + + fn name(&self) -> &str { + self.name.as_str() + } +} + +#[extendr] +fn aux_func() { +} + + +// Macro to generate exports +extendr_module! { + mod classes; + impl Person; + fn aux_func; +} +``` + +The `#[extendr]` attribute causes the compiler to generate wrapper and +registration functions for R which are called when the package is loaded. + +On R's side, users can access to the above Rust functions as follows: + +``` r +# call function +aux_func() + +# create Person object +p <- Person$new() +p$set_name("foo") +p$name() # "foo" is returned +``` + +The `extendr_module!` macro lists the module name and exported functions and +interfaces. + +This library aims to provide an interface that will be familiar to first-time +users of Rust or indeed any compiled language. + +Anyone who knows the R library should be able to write R extensions. + +## Wrappers for R types + +Extendr provides a number of wrappers for R types. These fall into three +categories, scalar types such as a single integer, vector types which are an +array of a scalar type and linked list types used to represent R code and call +arguments. + +### Scalar types + +| R type | Extendr wrapper | Deref type: `&*object` | +|-------------|----------------------------------------|------------------------| +| `Any` | `extendr_api::robj::Robj` | N/A | +| `character` | `extendr_api::wrapper::Rstr` | N/A | +| `integer` | `extendr_api::wrapper::Rint` | N/A | +| `double` | `extendr_api::wrapper::Rfloat` | N/A | +| `complex` | `extendr_api::wrapper::Rcplx` | N/A | +| `extptr` | `extendr_api::wrapper::ExternalPtr` | `&T` / `&mut T` | + +### Vector types + +| R type | Extendr wrapper | Deref type: `&*object` | +|--------------|--------------------------------------|------------------------| +| `integer` | `extendr_api::wrapper::Integers` | `&[Rint]` | +| `double` | `extendr_api::wrapper::Doubles` | `&[Rfloat]` | +| `logical` | `extendr_api::wrapper::Logicals` | `&[Rbool]` | +| `complex` | `extendr_api::wrapper::Complexes` | `&[Rcplx]` | +| `string` | `extendr_api::wrapper::Strings` | `&[Rstr]` | +| `list` | `extendr_api::wrapper::List` | `&[Robj]` | +| `data.frame` | `extendr_api::wrapper::Dataframe` | `&[Robj]` | +| `expression` | `extendr_api::wrapper::Expression` | `&[Lang]` | + +### Linked list types + +| R type | Extendr wrapper | Deref type: `&*object` | +|------------|----------------------------------|------------------------| +| `pairlist` | `extendr_api::wrapper::Pairlist` | N/A | +| `lang` | `extendr_api::wrapper::Lang` | N/A | + +## Examples + +### Returning lists and strings + +Lists and strings in rust are vectors of R objects. These are represented by the +wrappers `List` and `Strings`. + +`List` contains a slice of `Robj` wrappers which can contain any R object. + +`Strings` contains a slice of `Rstr` wrappers which can contain a single string. + +These examples show how to return a list or string to R from Rust. + +``` rust +use extendr_api::wrapper::{List, Strings}; +use extendr_api::list; + +fn get_strings() -> Strings { + Strings::from_values( + (0..10) + .map(|i| format!("number {}", i)) + ) +} + +fn get_named_list() -> List { + list!(x=1, y="xyz", z=()) +} + +fn get_unnamed_list() -> List { + List::from_values(0..10) +} +``` + +### Returning scalars + +Whilst we can use `i32` and `f64` in Extendr to return values. A better way is +to use the `Rint` and `Rfloat` wrappers which provide access to the `NA` value +used by R to represent missing data. + +``` rust +use extendr_api::scalar::{Rint, Rfloat}; + +// for .na() +use extendr_api::CanBeNA; + +fn get_int() -> Rint { + Rint::from(1) +} + +fn get_na_int() -> Rint { + Rint::na() +} + +fn get_float() -> Rfloat { + Rfloat::from(1.0) +} + +fn get_na_float() -> Rfloat { + Rfloat::na() +} +``` + +### Plotting a PNG file from Rust + +We can use Extendr to take advantage of the stats and plotting functions in R. + +For example, we could make a web server that returns plots of incoming data. + +``` rust +use extendr_api::{test, Result, eval_string, eval_string_with_params}; +use extendr_api::{Doubles, R}; + +fn main() { + test!{ + let x = Doubles::from_values((0..100).map(|i| i as f64 / 20.0)); + + // let y = Doubles::from_values(x.iter().map(|x| x.inner().sin())); + let y = Doubles::from_values((0..100).map(|i| (i as f64 / 20.0).sin())); + + // Set a PNG device + R!(r#"png("/tmp/sin_plot.png")"#)?; + + // Plot x and y + R!("plot({{&x}}, {{&y}})")?; + + // Linear model. + R!("abline(lm({{y}} ~ {{x}}))")?; + + // Flush the device to the image. + R!("dev.off()")?; + } +} +``` diff --git a/pkgdown/templates/navbar.html b/pkgdown/templates/navbar.html deleted file mode 100644 index 32cd35f..0000000 --- a/pkgdown/templates/navbar.html +++ /dev/null @@ -1,32 +0,0 @@ - -{{#navbar}} - -{{/navbar}} diff --git a/started.md b/started.qmd similarity index 95% rename from started.md rename to started.qmd index c35f2dc..997be3b 100644 --- a/started.md +++ b/started.qmd @@ -1,4 +1,6 @@ -# Getting started +--- +title: "Getting started" +--- Extendr is available on [crates.io](https://crates.io/crates/extendr-api).