diff --git a/NAMESPACE b/NAMESPACE index 912ec19..ee8477d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,6 +8,7 @@ export(req_perform) export(req_prepare) export(security_api_key) export(stabilize_string) +export(url_path_append) importFrom(fs,path) importFrom(httr2,req_perform) importFrom(rlang,":=") diff --git a/R/utils.R b/R/utils.R index b2ba268..08d03e2 100644 --- a/R/utils.R +++ b/R/utils.R @@ -34,3 +34,31 @@ compact_nested_list <- function(lst) { } return(purrr::compact(lst)) } + +#' Add path elements to a URL +#' +#' Append zero or more path elements to a URL without duplicating "/" +#' characters. Based on [httr2::req_url_path_append()]. +#' +#' @param url A URL to modify. +#' @param ... Path elements to append, as strings. +#' +#' @return A modified URL. +#' @export +#' +#' @examples +#' url_path_append("https://example.com", "api", "v1", "users") +#' url_path_append("https://example.com/", "/api", "/v1", "/users") +#' url_path_append("https://example.com/", "/api/v1/users") +url_path_append <- function(url, ...) { + url <- httr2::url_parse(url) + url$path <- .path_merge(url$path, ...) + return(httr2::url_build(url)) +} + +.path_merge <- function(...) { + path <- paste(c(...), collapse = "/") + path <- sub("^([^/])", "/\\1", path) + path <- gsub("/+", "/", path) + return(sub("/$", "", path)) +} diff --git a/man/url_path_append.Rd b/man/url_path_append.Rd new file mode 100644 index 0000000..a96c14c --- /dev/null +++ b/man/url_path_append.Rd @@ -0,0 +1,25 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils.R +\name{url_path_append} +\alias{url_path_append} +\title{Add path elements to a URL} +\usage{ +url_path_append(url, ...) +} +\arguments{ +\item{url}{A URL to modify.} + +\item{...}{Path elements to append, as strings.} +} +\value{ +A modified URL. +} +\description{ +Append zero or more path elements to a URL without duplicating "/" +characters. Based on \code{\link[httr2:req_url]{httr2::req_url_path_append()}}. +} +\examples{ +url_path_append("https://example.com", "api", "v1", "users") +url_path_append("https://example.com/", "/api", "/v1", "/users") +url_path_append("https://example.com/", "/api/v1/users") +} diff --git a/tests/testthat/test-req_query.R b/tests/testthat/test-req_query.R index 69d8caa..f3959fc 100644 --- a/tests/testthat/test-req_query.R +++ b/tests/testthat/test-req_query.R @@ -13,7 +13,7 @@ test_that("req_prepare() uses query parameters", { ) }) -test_that("req_prepare() smushes and concatenates multi-value query parameters", { +test_that("req_prepare() smushes & concatenates multi-value query parameters", { test_result <- req_prepare( base_url = "https://example.com", query = list( diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R new file mode 100644 index 0000000..0bec1d5 --- /dev/null +++ b/tests/testthat/test-utils.R @@ -0,0 +1,15 @@ +test_that("Can build clean urls", { + expected_result <- "https://example.com/api/v1/users" + expect_identical( + url_path_append("https://example.com", "api", "v1", "users"), + expected_result + ) + expect_identical( + url_path_append("https://example.com/", "/api", "/v1", "/users"), + expected_result + ) + expect_identical( + url_path_append("https://example.com/", "/api/v1/users"), + expected_result + ) +})