Skip to content

Commit

Permalink
Merge pull request #2 from etiennebacher/remove-deps
Browse files Browse the repository at this point in the history
  • Loading branch information
JosiahParry authored Jan 20, 2024
2 parents 97014ff + aaf79a1 commit ae74633
Show file tree
Hide file tree
Showing 15 changed files with 118 additions and 127 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.Rproj.user
src/rust/vendor
src/vendor
docs
15 changes: 7 additions & 8 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
Package: b64
Title: Fast and Vectorized Base 64 Engine
Version: 0.1.0
Authors@R:
Version: 0.1.0.9000
Authors@R: c(
person("Josiah", "Parry", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-9910-865X"))
comment = c(ORCID = "0000-0001-9910-865X")),
person("Etienne", "Bacher", email = "[email protected]", role = "ctb",
comment = c(ORCID = "0000-0002-9271-5075")))
Description: Provides a fast, lightweight, and vectorized base 64 engine
to encode and decode character and raw vectors as well as files stored
on disk. Common base 64 alphabets are supported out of the box
Expand All @@ -14,13 +16,10 @@ License: MIT + file LICENSE
Encoding: UTF-8
Language: en
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
RoxygenNote: 7.3.0
Config/rextendr/version: 0.3.1.9000
SystemRequirements: Cargo (Rust's package manager), rustc
Imports:
blob,
cli,
rlang
Suggests:
blob,
testthat (>= 3.0.0)
Config/testthat/edition: 3
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ export(engine)
export(new_alphabet)
export(new_config)
export(new_engine)
importFrom(blob,blob)
useDynLib(b64, .registration = TRUE)
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# b64 (development version)

* All hard dependencies were removed (#2, @etiennebacher).

# b64 0.1.0

* Initial CRAN submission.
11 changes: 5 additions & 6 deletions R/alphabet.R
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
#' new_alphabet("qwertyuiop[]asdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890")
#' @returns an object of class `alphabet`
alphabet <- function(which = "standard") {
rlang::arg_match(
match.arg(
which,
values = c("standard", "bcrypt", "bin_hex", "crypt", "imap_mutf7", "url_safe")
choices = c("standard", "bcrypt", "bin_hex", "crypt", "imap_mutf7", "url_safe")
)
structure(alphabet_(which), class = "alphabet")
}
Expand All @@ -42,10 +42,9 @@ alphabet <- function(which = "standard") {
new_alphabet <- function(chars) {
n <- nchar(chars)
if (nchar(chars) != 64) {
cli::cli_abort(
c(
"{.arg chars} must be 64 unique characters",
"i" = "{n} characters provided"
stop(
paste(
"`chars` must contain 64 unique characters. Only", n, "characters were provided."
)
)
}
Expand Down
1 change: 0 additions & 1 deletion R/b64-package.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#' @keywords internal
#' @importFrom blob blob
"_PACKAGE"

## usethis namespace: start
Expand Down
4 changes: 2 additions & 2 deletions R/config.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ new_config <- function(
decode_padding_mode = c("canonical", "indifferent", "none")
) {

padding_mode <- rlang::arg_match0(
padding_mode <- match.arg(
decode_padding_mode,
values = c("canonical", "indifferent", "none")
choices = c("canonical", "indifferent", "none")
)

res <- new_config_(
Expand Down
4 changes: 2 additions & 2 deletions R/encode.R
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ decode <- function(what, eng = engine()) {
#' @name encode
encode_file <- function(path, eng = engine()) {
if (!file.exists(path)) {
cli::cli_abort("{.arg path} does not exist")
stop(paste0("`", path, "` does not exist"))
}

encode_file_(path, eng)
Expand All @@ -56,7 +56,7 @@ encode_file <- function(path, eng = engine()) {
#' @rdname encode
decode_file <- function(path, eng = engine()) {
if (!file.exists(path)) {
cli::cli_abort("{.arg path} does not exist")
stop(paste0("`", path, "` does not exist"))
}

decode_file_(path, eng)
Expand Down
22 changes: 11 additions & 11 deletions R/engine.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,26 @@
#' new_engine(alphabet("bcrypt"), new_config())
engine <- function(which = "standard") {
provided <- c("standard", "standard_no_pad", "url_safe", "url_safe_no_pad")
rlang::arg_match0(which, provided)
match.arg(which, choices = provided)
structure(engine_(which), class = "engine")
}

#' @export
#' @rdname engine
new_engine <- function(.alphabet = alphabet(), .config = new_config()) {

if (!rlang::inherits_only(.alphabet, "alphabet")) {
cli::cli_abort(
c(
"{.arg .alphabet} is not an object of class {.cls alphabet}",
"*" = "use {.fn alphabet} for a standard base64 alphabet"
if (!inherits(.alphabet, "alphabet")) {
stop(
paste(
"`.alphabet` is not an object of class 'alphabet'.\n" ,
"Use `alphabet()` for a standard base64 alphabet."
)
)
} else if (!rlang::inherits_only(.config, "engine_config")) {
cli::cli_abort(
c(
"{.arg config} is not a {.cls engine_config} object",
"*" = "create one with {.fn new_config}"
} else if (!inherits(.config, "engine_config")) {
stop(
paste(
"`.config` is not an object of class 'engine_config'.\n" ,
"Create one with `new_config()`."
)
)
}
Expand Down
22 changes: 10 additions & 12 deletions R/extendr-wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,28 @@ new_config_ <- function(encode_padding, decode_padding_trailing_bits, decode_pad

print_config_ <- function(config) .Call(wrap__print_config_, config)

#' Utility Functions
#'
#' Utility Functions
#'
#' Functions to perform common tasks when working with base64 encoded strings.
#'
#'
#' @details
#'
#' `b64_chunk()` splits a character vector of base64 encoded strings into chunks of a
#'
#' `b64_chunk()` splits a character vector of base64 encoded strings into chunks of a
#' specified width.
#'
#'
#' `b64_wrap()` wraps a character vector of base64 encoded strings with a newline character.
#'
#'
#' @returns
#'
#'
#' - `b64_chunk()` returns a list of character vectors.
#' - `b64_wrap()` returns a scalar character vector.
#'
#'
#' @examples
#' encoded <- encode("Hello, world!")
#' chunked <- b64_chunk(encoded, 4)
#' chunked
#'
#'
#' b64_wrap(chunked, "\n")
#'
#'
#' @param width a numeric scalar defining the width of the chunks. Must be divisible by 4.
#' @param encoded a character vector of base64 encoded strings.
#' @export
Expand Down
5 changes: 3 additions & 2 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ hello <- encode("Hello, from extendr")
hello
```

Decode using `decode()`
Decode using `decode()`. Note that the returned object will always have the `"blob"` class. To achieve 0 dependencies, the `blob` package is only listed as a suggested dependency but if you attach it, its print method will be used.

```{r}
library(blob)
decoded <- decode(hello)
decoded
```
Expand All @@ -66,7 +67,7 @@ encoded <- encode(lorem)
encoded
```

We can decode all of these using `decode()` as well. This will always return a `blob` object.
We can decode all of these using `decode()` as well.

```{r}
decode(encoded)
Expand Down
41 changes: 22 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

<!-- README.md is generated from README.Rmd. Please edit that file -->

# b64
# b64 <img src="man/figures/logo.svg" align="right" height="139" alt="" />

<!-- badges: start -->

Expand Down Expand Up @@ -31,9 +31,13 @@ hello
#> [1] "SGVsbG8sIGZyb20gZXh0ZW5kcg=="
```

Decode using `decode()`
Decode using `decode()`. Note that the returned object will always have
the `"blob"` class. To achieve 0 dependencies, the `blob` package is
only listed as a suggested dependency but if you attach it, its print
method will be used.

``` r
library(blob)
decoded <- decode(hello)
decoded
#> <blob[1]>
Expand All @@ -54,28 +58,27 @@ Both `encode()` and `decode()` are vectorized.
``` r
lorem <- unlist(lorem::ipsum(5, 1, 5))
lorem
#> [1] "Sit ligula senectus litora viverra consequat."
#> [2] "Consectetur vulputate vivamus sapien a ridiculus porta."
#> [3] "Ipsum orci cras posuere lacus."
#> [4] "Lorem nostra hendrerit nascetur vel duis consequat."
#> [5] "Adipiscing dui blandit vestibulum bibendum?"
#> [1] "Elit porttitor litora phasellus primis."
#> [2] "Sit vel natoque eu quisque."
#> [3] "Sit accumsan elementum pharetra aliquet parturient ullamcorper."
#> [4] "Consectetur iaculis nunc elementum."
#> [5] "Dolor donec iaculis sem."

encoded <- encode(lorem)
encoded
#> [1] "U2l0IGxpZ3VsYSBzZW5lY3R1cyBsaXRvcmEgdml2ZXJyYSBjb25zZXF1YXQu"
#> [2] "Q29uc2VjdGV0dXIgdnVscHV0YXRlIHZpdmFtdXMgc2FwaWVuIGEgcmlkaWN1bHVzIHBvcnRhLg=="
#> [3] "SXBzdW0gb3JjaSBjcmFzIHBvc3VlcmUgbGFjdXMu"
#> [4] "TG9yZW0gbm9zdHJhIGhlbmRyZXJpdCBuYXNjZXR1ciB2ZWwgZHVpcyBjb25zZXF1YXQu"
#> [5] "QWRpcGlzY2luZyBkdWkgYmxhbmRpdCB2ZXN0aWJ1bHVtIGJpYmVuZHVtPw=="
#> [1] "RWxpdCBwb3J0dGl0b3IgbGl0b3JhIHBoYXNlbGx1cyBwcmltaXMu"
#> [2] "U2l0IHZlbCBuYXRvcXVlIGV1IHF1aXNxdWUu"
#> [3] "U2l0IGFjY3Vtc2FuIGVsZW1lbnR1bSBwaGFyZXRyYSBhbGlxdWV0IHBhcnR1cmllbnQgdWxsYW1jb3JwZXIu"
#> [4] "Q29uc2VjdGV0dXIgaWFjdWxpcyBudW5jIGVsZW1lbnR1bS4="
#> [5] "RG9sb3IgZG9uZWMgaWFjdWxpcyBzZW0u"
```

We can decode all of these using `decode()` as well. This will always
return a `blob` object.
We can decode all of these using `decode()` as well.

``` r
decode(encoded)
#> <blob[5]>
#> [1] blob[45 B] blob[55 B] blob[30 B] blob[51 B] blob[43 B]
#> [1] blob[39 B] blob[27 B] blob[63 B] blob[35 B] blob[24 B]
```

## Encoding and decoding files
Expand All @@ -99,8 +102,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 b64 39.8ms 41.3ms 24.0 24MB 0
#> 2 base64enc 112.1ms 115.2ms 8.56 66.5MB 17.1
#> 1 b64 67.5ms 74.2ms 13.7 24.1MB 1.96
#> 2 base64enc 177.9ms 183.3ms 5.50 66.9MB 11.0
```

While the encoding is very impressive, better yet is the decoding
Expand All @@ -122,8 +125,8 @@ bench::mark(
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 b64 16.1ms 16.8ms 56.1 18MB 9.34
#> 2 base64enc 209.1ms 210.7ms 4.75 18MB 0
#> 1 b64 43.4ms 51.7ms 19.7 18.1MB 5.63
#> 2 base64enc 356.7ms 373.3ms 2.68 18.1MB 0
```

## Alternative engines
Expand Down
10 changes: 8 additions & 2 deletions man/b64-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions man/utils.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ae74633

Please sign in to comment.