From 6b6c10b8ccdb4fd282d14b8549e9598a39c8cafd Mon Sep 17 00:00:00 2001 From: Jon Harmon Date: Thu, 26 Oct 2023 08:48:27 -0500 Subject: [PATCH] Implement stabilize_string(). Closes #13. --- DESCRIPTION | 3 +- NAMESPACE | 1 + R/security.R | 3 -- R/stabilize.R | 42 +++++++++++++++++++++++ man/stabilize_string.Rd | 60 +++++++++++++++++++++++++++++++++ tests/testthat/test-stabilize.R | 10 ++++++ 6 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 R/stabilize.R create mode 100644 man/stabilize_string.Rd create mode 100644 tests/testthat/test-stabilize.R diff --git a/DESCRIPTION b/DESCRIPTION index fe66d04..f754e30 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -19,7 +19,8 @@ Imports: httr2 (>= 0.2.3.9000), jsonlite, purrr, - rlang + rlang, + stbl Suggests: covr, testthat (>= 3.0.0) diff --git a/NAMESPACE b/NAMESPACE index 8557283..cffc4e0 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,5 +5,6 @@ S3method(.add_body,multipart) export(call_api) export(compact_nested_list) export(security_api_key) +export(stabilize_string) importFrom(fs,path) importFrom(rlang,":=") diff --git a/R/security.R b/R/security.R index 82aa4b5..4de59d8 100644 --- a/R/security.R +++ b/R/security.R @@ -1,6 +1,3 @@ -# @param ... Additional arguments, which depend on the location of the API key. - - #' Authenticate with an API key #' #' Many APIs provide API keys that can be used to authenticate requests (or, diff --git a/R/stabilize.R b/R/stabilize.R new file mode 100644 index 0000000..d6b6f0f --- /dev/null +++ b/R/stabilize.R @@ -0,0 +1,42 @@ +#' Ensure an argument is a length-1 character +#' +#' Calls to APIs often require a string argument. This function ensures that +#' those arguments are length-1, non-`NA` character vectors, or length-1, +#' non-`NA` vectors that can be coerced to character vectors. This is intended +#' to ensure that calls to the API will not fail with predictable errors, thus +#' avoiding unnecessary internet traffic. +#' +#' @inheritParams rlang::args_error_context +#' @inheritParams stbl::stabilize_chr_scalar +#' @inheritDotParams stbl::stabilize_chr_scalar x_class +#' +#' @return `x` coerced to a length-1 character vector, if possible. +#' @export +#' +#' @examples +#' stabilize_string("a") +#' stabilize_string(1.1) +#' x <- letters +#' try(stabilize_string(x)) +#' x <- NULL +#' try(stabilize_string(x)) +#' x <- character() +#' try(stabilize_string(x)) +#' x <- NA +#' try(stabilize_string(x)) +stabilize_string <- function(x, + ..., + regex = NULL, + arg = rlang::caller_arg(x), + call = rlang::caller_env()) { + stbl::stabilize_chr_scalar( + x, + allow_null = FALSE, + allow_zero_length = FALSE, + allow_na = FALSE, + regex = regex, + x_arg = arg, + call = call, + ... + ) +} diff --git a/man/stabilize_string.Rd b/man/stabilize_string.Rd new file mode 100644 index 0000000..645270d --- /dev/null +++ b/man/stabilize_string.Rd @@ -0,0 +1,60 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/stabilize.R +\name{stabilize_string} +\alias{stabilize_string} +\title{Ensure an argument is a length-1 character} +\usage{ +stabilize_string( + x, + ..., + regex = NULL, + arg = rlang::caller_arg(x), + call = rlang::caller_env() +) +} +\arguments{ +\item{x}{The argument to stabilize.} + +\item{...}{ + Arguments passed on to \code{\link[stbl:stabilize_chr_scalar]{stbl::stabilize_chr_scalar}} + \describe{ + \item{\code{x_class}}{Character. The class name of \code{x} to use in error messages. Use +this if you remove a special class from \code{x} before checking its coercion, +but want the error message to match the original class.} + }} + +\item{regex}{Character scalar. An optional regex pattern to compare the +value(s) of \code{x} against. If a complex regex pattern throws an error, try +installing the stringi package with \code{install.packages("stringi")}.} + +\item{arg}{An argument name as a string. This argument +will be mentioned in error messages as the input that is at the +origin of a problem.} + +\item{call}{The execution environment of a currently +running function, e.g. \code{caller_env()}. The function will be +mentioned in error messages as the source of the error. See the +\code{call} argument of \code{\link[rlang:abort]{abort()}} for more information.} +} +\value{ +\code{x} coerced to a length-1 character vector, if possible. +} +\description{ +Calls to APIs often require a string argument. This function ensures that +those arguments are length-1, non-\code{NA} character vectors, or length-1, +non-\code{NA} vectors that can be coerced to character vectors. This is intended +to ensure that calls to the API will not fail with predictable errors, thus +avoiding unnecessary internet traffic. +} +\examples{ +stabilize_string("a") +stabilize_string(1.1) +x <- letters +try(stabilize_string(x)) +x <- NULL +try(stabilize_string(x)) +x <- character() +try(stabilize_string(x)) +x <- NA +try(stabilize_string(x)) +} diff --git a/tests/testthat/test-stabilize.R b/tests/testthat/test-stabilize.R new file mode 100644 index 0000000..9d3b505 --- /dev/null +++ b/tests/testthat/test-stabilize.R @@ -0,0 +1,10 @@ +test_that("stabilize_string() checks strings", { + expect_error(stabilize_string(letters), class = "stbl_error_non_scalar") + expect_error(stabilize_string(NULL), class = "stbl_error_bad_null") + expect_error(stabilize_string(character()), class = "stbl_error_bad_empty") + expect_error(stabilize_string(NA), class = "stbl_error_bad_na") + expect_identical( + stabilize_string("a"), + "a" + ) +})