blob/0000755000176200001440000000000014405053106011166 5ustar liggesusersblob/NAMESPACE0000644000176200001440000000142514133350505012410 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(as.blob,default) S3method(format,blob) S3method(obj_print_data,blob) S3method(vec_cast,blob) S3method(vec_cast.blob,blob) S3method(vec_cast.blob,character) S3method(vec_cast.blob,default) S3method(vec_cast.blob,integer) S3method(vec_cast.blob,list) S3method(vec_cast.blob,raw) S3method(vec_cast.blob,vctrs_list_of) S3method(vec_ptype2,blob) S3method(vec_ptype2.blob,blob) S3method(vec_ptype2.blob,default) S3method(vec_ptype2.blob,list) S3method(vec_ptype2.list,blob) S3method(vec_ptype_abbr,blob) S3method(vec_ptype_full,blob) export(as.blob) export(as_blob) export(blob) export(is_blob) export(new_blob) export(validate_blob) export(vec_cast.blob) export(vec_ptype2.blob) import(rlang) import(vctrs) importFrom(methods,setOldClass) blob/LICENSE0000644000176200001440000000005214133350505012171 0ustar liggesusersYEAR: 2020 COPYRIGHT HOLDER: blob authors blob/README.md0000644000176200001440000001110614405017272012450 0ustar liggesusers [![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) [![rcc](https://github.com/tidyverse/blob/workflows/rcc/badge.svg)](https://github.com/tidyverse/blob/actions) [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/blob)](https://cran.r-project.org/package=blob) [![Coverage Status](https://codecov.io/gh/tidyverse/blob/branch/main/graph/badge.svg)](https://app.codecov.io/gh/tidyverse/blob) # blob ## Overview The goal of blob is to provide a simple S3 class to represent a vector of binary objects, aka blobs. The `blob` class is a lightweight wrapper around a list of raw vectors, suitable for inclusion in a data frame. In most cases you will not need to use this package explicitly: it will be used transparently by packages that need to load BLOB columns from databases or binary file formats. ## Installation
# The easiest way to get blob is to install the whole tidyverse:
install.packages("tidyverse")

# Alternatively, install just blob:
install.packages("blob")

# Or the the development version from GitHub:
# install.packages("devtools")
devtools::install_github("tidyverse/blob")
## Example To create a blob, use `blob()`, `new_blob()` or `as_blob()`:
library(blob)

x1 <- charToRaw("Good morning")
x2 <- as.raw(c(0x48, 0x65, 0x6c, 0x6c, 0x6f))

new_blob(list(x1, x2))
#> <blob[2]>
#> [1] blob[12 B] blob[5 B]
blob(x1, x2)
#> <blob[2]>
#> [1] blob[12 B] blob[5 B]

as_blob(c("Good morning", "Good evening"))
#> <blob[2]>
#> [1] blob[12 B] blob[12 B]
------------------------------------------------------------------------ Please note that the ‘blob’ project is released with a [Contributor Code of Conduct](https://github.com/tidyverse/blob/blob/main/CODE_OF_CONDUCT.md). By contributing to this project, you agree to abide by its terms. blob/man/0000755000176200001440000000000014405016202011735 5ustar liggesusersblob/man/blob.Rd0000644000176200001440000000174114133350505013152 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/blob.R \name{blob} \alias{blob} \alias{new_blob} \alias{validate_blob} \alias{as_blob} \alias{is_blob} \title{Construct a blob object} \usage{ blob(...) new_blob(x = list()) validate_blob(x) as_blob(x) is_blob(x) } \arguments{ \item{...}{Individual raw vectors} \item{x}{A list of raw vectors, or other object to coerce} } \description{ \code{new_blob()} is a low-level constructor that takes a list of raw vectors. \code{blob()} constructs a blob from individual raw vectors. \code{as_blob()} and \code{is_blob()} are simple forwarders to \code{\link[vctrs:vec_cast]{vctrs::vec_cast()}} and \code{\link[=inherits]{inherits()}}, respectively. } \examples{ x1 <- charToRaw("Good morning") x2 <- as.raw(c(0x48, 0x65, 0x6c, 0x6c, 0x6f)) new_blob(list(x1, x2)) blob(x1, x2) as.blob(c("Good morning", "Good evening")) } \seealso{ \code{\link[=as.blob]{as.blob()}} for the legacy interface for specifying casts. } blob/man/as.blob.Rd0000644000176200001440000000120614133350505013550 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/blob.R \name{as.blob} \alias{as.blob} \title{Deprecated generic} \usage{ as.blob(x, ...) } \arguments{ \item{x}{An object.} \item{...}{Passed on to methods.} } \description{ The \code{as.blob()} generic has been deprecated in favor of the \code{\link[=as_blob]{as_blob()}} function (for users) and the \code{\link[=vec_cast.blob]{vec_cast.blob()}} method (for implementers). Implement a \code{vec_cast.blob.myclass()} method to support coercing objects of your class to blobs. See \code{\link[vctrs:vec_cast]{vctrs::vec_cast()}} for more detail. } \keyword{internal} blob/man/vec_cast.blob.Rd0000644000176200001440000000116314210206472014735 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/cast.R \name{vec_cast.blob} \alias{vec_cast.blob} \title{Casting} \usage{ \method{vec_cast}{blob}(x, to, ...) } \arguments{ \item{x}{Vectors to cast.} \item{to}{Type to cast to. If \code{NULL}, \code{x} will be returned as is.} \item{...}{For \code{vec_cast_common()}, vectors to cast. For \code{vec_cast()}, \code{vec_cast_default()}, and \code{vec_restore()}, these dots are only for future extensions and should be empty.} } \description{ Double dispatch methods to support \code{\link[vctrs:vec_cast]{vctrs::vec_cast()}}. } \keyword{internal} blob/man/vec_ptype2.blob.Rd0000644000176200001440000000123614405016202015223 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/coerce.R \name{vec_ptype2.blob} \alias{vec_ptype2.blob} \title{Coercion} \usage{ \method{vec_ptype2}{blob}(x, y, ..., x_arg = "", y_arg = "") } \arguments{ \item{x, y}{Vector types.} \item{...}{These dots are for future extensions and must be empty.} \item{x_arg, y_arg}{Argument names for \code{x} and \code{y}. These are used in error messages to inform the user about the locations of incompatible types (see \code{\link[vctrs:stop_incompatible_type]{stop_incompatible_type()}}).} } \description{ Double dispatch methods to support \code{\link[vctrs:vec_ptype2]{vctrs::vec_ptype2()}}. } blob/DESCRIPTION0000644000176200001440000000223614405053106012677 0ustar liggesusersPackage: blob Title: A Simple S3 Class for Representing Vectors of Binary Data ('BLOBS') Version: 1.2.4 Authors@R: c( person("Hadley", "Wickham", role = "aut"), person("Kirill", "Müller", , "kirill@cynkra.com", role = "cre"), person("RStudio", role = c("cph", "fnd")) ) Description: R's raw vector is useful for storing a single binary object. What if you want to put a vector of them in a data frame? The 'blob' package provides the blob object, a list of raw vectors, suitable for use as a column in data frame. License: MIT + file LICENSE URL: https://blob.tidyverse.org, https://github.com/tidyverse/blob BugReports: https://github.com/tidyverse/blob/issues Imports: methods, rlang, vctrs (>= 0.2.1) Suggests: covr, crayon, pillar (>= 1.2.1), testthat Config/autostyle/scope: line_breaks Config/autostyle/strict: false Config/Needs/website: tidyverse/tidytemplate Encoding: UTF-8 RoxygenNote: 7.2.3 NeedsCompilation: no Packaged: 2023-03-17 09:42:50 UTC; kirill Author: Hadley Wickham [aut], Kirill Müller [cre], RStudio [cph, fnd] Maintainer: Kirill Müller Repository: CRAN Date/Publication: 2023-03-17 12:00:06 UTC blob/tests/0000755000176200001440000000000014133350505012331 5ustar liggesusersblob/tests/testthat/0000755000176200001440000000000014405053106014170 5ustar liggesusersblob/tests/testthat/blob.txt0000644000176200001440000000007014224463610015650 0ustar liggesusers [1] blob[4 B] blob[2.05 kB] blob[1.05 MB] blob/tests/testthat/test-missing.R0000644000176200001440000000111214133350505016735 0ustar liggesuserscontext("missing") test_that("is.na detects nulls", { x <- blob(as.raw(1), NULL, as.raw(2), NULL) expect_equal(is.na(x), c(FALSE, TRUE, FALSE, TRUE)) }) test_that("is.na<- sets missing values", { x <- blob(!!!as.raw(1:4)) is.na(x) <- (1:4 %% 2 == 0) expect_equal(x, blob(as.raw(1), NULL, as.raw(3), NULL)) }) test_that("is.na<- auto-expansion for logical indexes", { x <- blob(!!!as.raw(1:4)) expect_error(is.na(x) <- rep(TRUE, 5)) }) test_that("is.na<- auto-expansion for character indices", { x <- blob(!!!as.raw(1:4)) expect_error(is.na(x) <- letters[1:2]) }) blob/tests/testthat/test-construction.R0000644000176200001440000000040114133350505020016 0ustar liggesuserscontext("construction") test_that("input must be list of raw blobs", { # error from vctrs package expect_error(new_blob(1)) expect_error(blob(1), "must be a list of raw vectors") expect_error(blob(1, as.raw(1)), "must be a list of raw vectors") }) blob/tests/testthat/test-cast.R0000644000176200001440000000175614224463735016247 0ustar liggesuserscontext("test-cast") test_that("casting with as.blob()", { # Deprecated in v1.2.0 local_lifecycle_silence() expect_identical(as.blob(blob(raw(1))), blob(raw(1))) expect_identical(as.blob(list(raw(1))), blob(raw(1))) expect_identical(as.blob(raw(1)), blob(raw(1))) expect_identical(as.blob(1:3), blob(as.raw(1), as.raw(2), as.raw(3))) expect_identical(as.blob(c("abc", "def")), blob(charToRaw("abc"), charToRaw("def"))) }) test_that("casting with as_blob()", { expect_identical(as_blob(blob(raw(1))), blob(raw(1))) expect_identical(as_blob(list(raw(1))), blob(raw(1))) expect_identical(as_blob(raw(1)), blob(raw(1))) expect_identical(blob(!!!as.raw(1:3)), blob(as.raw(1), as.raw(2), as.raw(3))) expect_identical(as_blob(c("abc", "def")), blob(charToRaw("abc"), charToRaw("def"))) }) test_that("NA_character_ is converted to missing blob()", { expect_identical(as_blob(NA_character_), blob(NULL)) expect_identical(as_blob(c("1", NA_character_)), blob(as.raw(0x031), NULL)) }) blob/tests/testthat/test-accessors.R0000644000176200001440000000324514133350505017262 0ustar liggesuserscontext("accessors") test_that("subsetting blob returns blob", { x <- blob(!!!as.raw(1:5)) expect_s3_class(x[1], "blob") }) test_that("subsetting can return NA", { x <- blob(!!!as.raw(1:5)) expect_identical(x[NA_integer_], blob(NULL)) expect_identical(x[c(5, NA)], blob(as.raw(5L), NULL)) }) test_that("subset assignment works", { x <- blob(!!!as.raw(1:5)) x[3] <- blob(raw(1)) expect_identical(x, blob(!!!as.raw(c(1:2, 0L, 4:5)))) x[[4]] <- raw(1) expect_identical(x, blob(!!!as.raw(c(1:2, 0L, 0L, 5L)))) x[7] <- blob(raw(1)) expect_identical(x, blob(!!!as.raw(c(1:2, 0L, 0L, 5L)), NULL, raw(1))) }) test_that("can't insert objects of incorrect type", { x <- blob(!!!as.raw(1:5)) expect_error(x[[1]] <- 1, class = "vctrs_error_incompatible", fixed = TRUE) expect_error(x[1] <- 1, class = "vctrs_error_incompatible", fixed = TRUE) }) test_that("can insert raw or NULL", { x <- blob(!!!as.raw(1:4)) x[[1]] <- as.raw(0) x[2] <- list(as.raw(0)) x[[3]] <- NULL x[4] <- list(NULL) expect_equal(x, blob(as.raw(0), as.raw(0), NULL, NULL)) }) test_that("can combine", { expect_identical( c(blob(raw(4), raw(5)), blob(raw(7))), blob(raw(4), raw(5), raw(7)) ) expect_identical( # Doesn't work with c() vec_c(list(raw(4), raw(5)), blob(raw(7))), blob(raw(4), raw(5), raw(7)) ) expect_identical( vec_c(list(raw(7)), blob(raw(4), raw(5)), list(raw(7))), blob(raw(7), raw(4), raw(5), raw(7)) ) expect_identical( vec_c(NA, blob()), blob(NULL) ) expect_identical( c(blob(), NA), blob(NULL) ) expect_error( c(blob(raw(4), raw(5)), raw(7)) ) expect_error( c(blob(raw(4), raw(5)), 7) ) }) blob/tests/testthat/test-format.R0000644000176200001440000000172514210206472016565 0ustar liggesuserscontext("format") expect_format_equal <- function(formatted, result) { expect_equal( paste(formatted, collapse = "\n"), paste(result, collapse = "\n") ) } test_that("unequal sizes", { skip_on_cran() x <- blob(raw(2**2), raw(2**11), raw(2**20)) expect_format_equal( format(x), c( "blob[4 B]", "blob[2.05 kB]", "blob[1.05 MB]" ) ) expect_format_equal( format(x, trim = FALSE), c( "blob[ 4 B]", "blob[2.05 kB]", "blob[1.05 MB]" ) ) }) test_that("similar sizes", { skip_on_cran() x <- blob(raw(2**10), raw(2**11), raw(2**12)) expect_format_equal( format(x), c( "blob[1.02 kB]", "blob[2.05 kB]", "blob[4.10 kB]" ) ) }) test_that("empty", { x <- blob() expect_format_equal( format(x), character() ) }) test_that("output", { skip_on_cran() x <- blob(raw(2**2), raw(2**11), raw(2**20)) expect_known_output(print(x), "blob.txt") }) blob/tests/testthat/helper-deprecate.R0000644000176200001440000000006014210206472017520 0ustar liggesusers# scoped_lifecycle_errors(rlang::caller_env(8)) blob/tests/testthat.R0000644000176200001440000000006414133350505014314 0ustar liggesuserslibrary(testthat) library(blob) test_check("blob") blob/R/0000755000176200001440000000000014224476732011404 5ustar liggesusersblob/R/zzz.R0000644000176200001440000000016414133350505012351 0ustar liggesusers# nocov start .onLoad <- function(...) { s3_register("pillar::pillar_shaft", "blob") invisible() } # nocov end blob/R/util.R0000644000176200001440000000041614133350505012471 0ustar liggesusersis_raw_list <- function(x) { if (!is.list(x)) return(FALSE) raw <- vapply(x, is.raw, logical(1)) null <- vapply(x, is.null, logical(1)) if (!all(raw | null)) return(FALSE) TRUE } as_single_raw <- function(x) { if (is.na(x)) NULL else as.raw(x) } blob/R/cast.R0000644000176200001440000000253514224463717012465 0ustar liggesusers#' Casting #' #' Double dispatch methods to support [vctrs::vec_cast()]. #' #' @inheritParams vctrs::vec_cast #' #' @keywords internal #' @method vec_cast blob #' @export #' @export vec_cast.blob vec_cast.blob <- function(x, to, ...) UseMethod("vec_cast.blob") #' @method vec_cast.blob default #' @export vec_cast.blob.default <- function(x, to, ...) vec_default_cast(x, to, ...) #' @method vec_cast.blob blob #' @export vec_cast.blob.blob <- function(x, to, ...) x #' @method vec_cast.blob list #' @export vec_cast.blob.list <- function(x, to, ...) blob(!!!x) #' @method vec_cast.blob vctrs_list_of #' @export vec_cast.blob.vctrs_list_of <- function(x, to, ...) { new_blob(vec_cast(x, new_list_of(ptype = raw()))) } #' @method vec_cast.blob integer #' @export vec_cast.blob.integer <- function(x, to, ...) { signal_soft_deprecated("Coercing an integer vector to a blob is deprecated, please coerce to a list first.") blob(!!!lapply(x, as_single_raw)) } #' @method vec_cast.blob raw #' @export vec_cast.blob.raw <- function(x, to, ...) blob(x) #' @method vec_cast.blob character #' @export vec_cast.blob.character <- function(x, to, ...) { out <- as_blob(vector("list", length(x))) # charToRaw(NA_character_) == charToRaw("NA"), so only convert non-missing entries non_missing <- !is.na(x) out[non_missing] <- lapply(x[non_missing], charToRaw) out } blob/R/prettyunits.R0000644000176200001440000000236014210206472014125 0ustar liggesuserscompute_bytes <- function(bytes, smallest_unit = "B") { units0 <- c("B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") stopifnot( is.numeric(bytes), is.character(smallest_unit), length(smallest_unit) == 1, !is.na(smallest_unit), smallest_unit %in% units0 ) negative <- (bytes < 0) bytes <- abs(bytes) smallest_idx <- match(smallest_unit, units0) limits <- c(1000, 999950 * 1000^(seq_len(length(units0) - 2) - 1)) idx <- cut(bytes, c(0, limits, Inf), labels = FALSE, right = FALSE) idx <- pmax(idx, smallest_idx) amount <- bytes / signif(c(1, limits), 1)[idx] idx[is.na(idx)] <- smallest_idx unit <- units0[idx] data.frame( stringsAsFactors = FALSE, amount, unit, negative ) } pretty_bytes_default <- function(bytes) { szs <- compute_bytes(bytes) amt <- szs$amount * ifelse(szs$negative, -1, 1) is_int <- is.na(amt) | amt == as.integer(amt) ## String. For fractions we always show two fraction digits res <- ifelse( is_int, sprintf("%.0f%s", amt, ifelse(all(is_int) | (szs$unit == "B"), "", " ")), sprintf("%.2f", amt) ) format(paste(res, szs$unit), justify = "right") } pretty_bytes_nopad <- function(bytes) { sub("^\\s+", "", pretty_bytes_default(bytes)) } blob/R/coerce.R0000644000176200001440000000157414133350505012762 0ustar liggesusers#' Coercion #' #' Double dispatch methods to support [vctrs::vec_ptype2()]. #' #' @inheritParams vctrs::vec_ptype2 #' #' @method vec_ptype2 blob #' @export #' @export vec_ptype2.blob vec_ptype2.blob <- function(x, y, ..., x_arg = "", y_arg = "") UseMethod("vec_ptype2.blob", y) #' @method vec_ptype2.blob default #' @export vec_ptype2.blob.default <- function(x, y, ..., x_arg = "", y_arg = "") { vec_default_ptype2(x, y, x_arg = x_arg, y_arg = y_arg) } #' @method vec_ptype2.blob blob #' @export vec_ptype2.blob.blob <- function(x, y, ...) { new_blob(list()) } #' @method vec_ptype2.blob list #' @export vec_ptype2.blob.list <- function(x, y, ..., x_arg = "", y_arg = "") { check_raw_list(y, y_arg) new_blob(list()) } #' @method vec_ptype2.list blob #' @export vec_ptype2.list.blob <- function(x, y, ..., x_arg = "", y_arg = "") { check_raw_list(x, x_arg) new_blob(list()) } blob/R/blob.R0000644000176200001440000000373414133350505012440 0ustar liggesusers#' @import vctrs #' @import rlang NULL #' @importFrom methods setOldClass setOldClass(c("blob", "vctrs_list_of", "vctrs_vctr")) #' Construct a blob object #' #' `new_blob()` is a low-level constructor that takes a list of #' raw vectors. #' `blob()` constructs a blob from individual raw vectors. #' `as_blob()` and `is_blob()` are simple forwarders to [vctrs::vec_cast()] #' and [inherits()], respectively. #' #' @seealso [as.blob()] for the legacy interface for specifying casts. #' #' @param ... Individual raw vectors #' @param x A list of raw vectors, or other object to coerce #' @export #' @examples #' x1 <- charToRaw("Good morning") #' x2 <- as.raw(c(0x48, 0x65, 0x6c, 0x6c, 0x6f)) #' #' new_blob(list(x1, x2)) #' blob(x1, x2) #' #' as.blob(c("Good morning", "Good evening")) blob <- function(...) { x <- list2(...) validate_blob(x) new_blob(x) } #' @export #' @rdname blob new_blob <- function(x = list()) { new_list_of(x, ptype = raw(), class = "blob") } #' @export #' @rdname blob validate_blob <- function(x) { x_arg <- as_label(enexpr(x)) check_raw_list(x, x_arg) } check_raw_list <- function(x, x_arg) { if (!is_raw_list(x)) { stop("`", x_arg, "` must be a list of raw vectors", call. = FALSE) } } #' @export #' @rdname blob as_blob <- function(x) { vec_cast(x, new_blob()) } #' @export #' @rdname blob is_blob <- function(x) { vec_is(x, new_blob()) } #' Deprecated generic #' #' The `as.blob()` generic has been deprecated in favor of #' the [as_blob()] function (for users) and the [vec_cast.blob()] method #' (for implementers). #' Implement a `vec_cast.blob.myclass()` method to support #' coercing objects of your class to blobs. #' See [vctrs::vec_cast()] for more detail. #' #' @param x An object. #' @param ... Passed on to methods. #' #' @export #' @keywords internal as.blob <- function(x, ...) { signal_soft_deprecated("as.blob() is deprecated, use as_blob().") UseMethod("as.blob") } #' @export as.blob.default <- function(x, ...) { as_blob(x) } blob/R/compat-lifecycle.R0000644000176200001440000001375014224476732014755 0ustar liggesusers# nocov start --- compat-lifecycle # This file serves as a reference for currently unexported rlang # lifecycle functions. Please find the most recent version in rlang's # repository. These functions require rlang in your `Imports` # DESCRIPTION field but you don't need to import rlang in your # namespace. # Changelog # ========= # # 2021-04-19 # # - Removed `lifecycle()` function. You can now use the following in # your roxygen documentation to inline a badge: # # ``` # `r lifecycle::badge()` # ``` # # This is a build-time dependency on lifecycle so there is no need # to add lifecycle to Imports just to use badges. See also # `?usethis::use_lifecycle()` for importing or updating the badge # images in your package. # # - Soft-namespaced private objects. #' Signal deprecation #' #' @description #' #' These functions provide two levels of verbosity for deprecation #' warnings. #' #' * `signal_soft_deprecated()` warns only if called from the global #' environment (so the user can change their script) or from the #' package currently being tested (so the package developer can fix #' the package). #' #' * `warn_deprecated()` warns unconditionally. #' #' * `stop_defunct()` fails unconditionally. #' #' Both functions warn only once per session by default to avoid #' overwhelming the user with repeated warnings. #' #' @param msg The deprecation message. #' @param id The id of the deprecation. A warning is issued only once #' for each `id`. Defaults to `msg`, but you should give a unique ID #' when the message is built programmatically and depends on inputs. #' @param env The environment in which the soft-deprecated function #' was called. A warning is issued if called from the global #' environment. If testthat is running, a warning is also called if #' the retired function was called from the package being tested. #' #' @section Controlling verbosity: #' #' The verbosity of retirement warnings can be controlled with global #' options. You'll generally want to set these options locally with #' one of these helpers: #' #' * `with_lifecycle_silence()` disables all soft-deprecation and #' deprecation warnings. #' #' * `with_lifecycle_warnings()` enforces warnings for both #' soft-deprecated and deprecated functions. The warnings are #' repeated rather than signalled once per session. #' #' * `with_lifecycle_errors()` enforces errors for both #' soft-deprecated and deprecated functions. #' #' All the `with_` helpers have `scoped_` variants that are #' particularly useful in testthat blocks. #' #' @noRd NULL signal_soft_deprecated <- function(msg, id = msg, env = rlang::caller_env(2)) { msg <- .rlang_lifecycle_validate_message(msg) stopifnot( rlang::is_string(id), rlang::is_environment(env) ) if (rlang::is_true(rlang::peek_option("lifecycle_disable_warnings"))) { return(invisible(NULL)) } env_inherits_global <- function(env) { # `topenv(emptyenv())` returns the global env. Return `FALSE` in # that case to allow passing the empty env when the # soft-deprecation should not be promoted to deprecation based on # the caller environment. if (rlang::is_reference(env, emptyenv())) { return(FALSE) } rlang::is_reference(topenv(env), rlang::global_env()) } if (rlang::is_true(rlang::peek_option("lifecycle_verbose_soft_deprecation")) || env_inherits_global(env)) { warn_deprecated(msg, id) return(invisible(NULL)) } # Test for environment names rather than reference/contents because # testthat clones the namespace tested_package <- Sys.getenv("TESTTHAT_PKG") if (nzchar(tested_package) && identical(Sys.getenv("NOT_CRAN"), "true") && rlang::env_name(topenv(env)) == rlang::env_name(rlang::ns_env(tested_package))) { warn_deprecated(msg, id) return(invisible(NULL)) } rlang::signal(msg, "lifecycle_soft_deprecated") } warn_deprecated <- function(msg, id = msg) { msg <- .rlang_lifecycle_validate_message(msg) stopifnot(rlang::is_string(id)) if (rlang::is_true(rlang::peek_option("lifecycle_disable_warnings"))) { return(invisible(NULL)) } if (!rlang::is_true(rlang::peek_option("lifecycle_repeat_warnings")) && rlang::env_has(.rlang_lifecycle_deprecation_env, id)) { return(invisible(NULL)) } rlang::env_poke(.rlang_lifecycle_deprecation_env, id, TRUE); has_colour <- function() rlang::is_installed("crayon") && crayon::has_color() silver <- function(x) if (has_colour()) crayon::silver(x) else x if (rlang::is_true(rlang::peek_option("lifecycle_warnings_as_errors"))) { .Signal <- stop_defunct } else { .Signal <- .Deprecated } if (!rlang::is_true(rlang::peek_option("lifecycle_repeat_warnings"))) { msg <- paste0(msg, "\n", silver("This warning is displayed once per session.")) } .Signal(msg = msg) } .rlang_lifecycle_deprecation_env <- new.env(parent = emptyenv()) stop_defunct <- function(msg) { msg <- .rlang_lifecycle_validate_message(msg) err <- rlang::cnd( c("defunctError", "error", "condition"), old = NULL, new = NULL, package = NULL, message = msg ) stop(err) } local_lifecycle_silence <- function(frame = rlang::caller_env()) { rlang::local_options(.frame = frame, lifecycle_disable_warnings = TRUE ) } with_lifecycle_silence <- function(expr) { local_lifecycle_silence() expr } local_lifecycle_warnings <- function(frame = rlang::caller_env()) { rlang::local_options(.frame = frame, lifecycle_disable_warnings = FALSE, lifecycle_verbose_soft_deprecation = TRUE, lifecycle_repeat_warnings = TRUE ) } with_lifecycle_warnings <- function(expr) { local_lifecycle_warnings() expr } local_lifecycle_errors <- function(frame = rlang::caller_env()) { local_lifecycle_warnings(frame = frame) rlang::local_options(.frame = frame, lifecycle_warnings_as_errors = TRUE ) } with_lifecycle_errors <- function(expr) { local_lifecycle_errors() expr } .rlang_lifecycle_validate_message <- function(msg) { stopifnot(rlang::is_character(msg)) paste0(msg, collapse = "\n") } # nocov end blob/R/format.R0000644000176200001440000000170614405016305013006 0ustar liggesusers#' @export format.blob <- function(x, ...) { if (length(x) == 0) return(character()) ifelse(is.na(x), "", paste0("blob[", blob_size(x, ...), "]")) } #' @export obj_print_data.blob <- function(x, ...) { if (length(x) == 0) return() out <- stats::setNames(format(x), names(x)) print(out, quote = FALSE) invisible(x) } #' @export vec_ptype_abbr.blob <- function(x, ..., prefix_named, suffix_shape) { "blob" } #' @export vec_ptype_full.blob <- function(x, ...) { "blob" } blob_size <- function(x, digits = 3, trim = TRUE, ...) { x <- vapply(x, length, numeric(1)) if (isTRUE(trim)) { pretty_bytes_nopad(x) } else { pretty_bytes_default(x) } } # Dynamically exported, see zzz.R pillar_shaft.blob <- function(x, ...) { out <- ifelse( is.na(x), NA_character_, paste0(pillar::style_subtle("")) ) pillar::new_pillar_shaft_simple(out, align = "right") } blob/NEWS.md0000644000176200001440000000337014405017361012272 0ustar liggesusers # blob 1.2.4 (2023-03-17) ## Bug fixes - Fix argument consistency between S3 generics and methods. # blob 1.2.3 (2022-04-10) - `as_blob(NA_character_)` returns a missing `blob` instead of `as_blob("NA")` (#26, @michaelchirico). # blob 1.2.2 (2021-07-23) - Moved to "stable" lifecycle stage. - Remove `is_vector_s3()` (#19). # blob 1.2.1 - Inline prettyunits. - `vec_ptype2.hms.default()` forwards to `vec_default_ptype2()` for compatibility with vctrs 0.2.1. # blob 1.2.0 ## Breaking changes - The `blob` class is now based on `list_of(raw())` from the vctrs package (#11). This adds support for `vec_cast()` and `vec_ptype2()`. Some operations (such as subset assignment) are now stricter. The `new_blob()` constructor permits safe and fast construction of `blob` objects from a list, and `validate_blob()` checks an existing object for conformity with the rules. - The new `is_blob()` deprecates the existing `is.blob()`. `as.blob()` is deprecated in favor of `vec_cast()` or the new `as_blob()` (which is just a thin wrapper around `vec_cast()`). - Indexing a vector of blobs out of bounds now raises an error. Use `NA` as index to create a `NULL` blob. # blob 1.1.1 (2018-03-24) - Now suggesting *pillar* instead of importing *tibble*, and using colored formatting with the *prettyunits* package with `B` instead of `b` as units (#7, #9). - The blob class can now be used for S4 dispatch. - Calling `c()` on blob objects returns a blob. # blob 1.1.0 (2017-06-17) - New maintainer: Kirill Müller. - Added `as.blob.blob()`and `as.data.frame.blob()` methods (#3). - Size of very large blobs is displayed correctly. # blob 1.0.0 - Initial release. blob/MD50000644000176200001440000000241314405053106011476 0ustar liggesusers3f6337a043f09887871453ab2cd9661d *DESCRIPTION fc22d472c57070ab7425257e9105c1b3 *LICENSE 6d735311cb02c8484e5e25e7f8f0c17f *NAMESPACE d460f67fc08ca66d8fda4c5680e1bf77 *NEWS.md ab801417fd359a5619585b96ef5ece2a *R/blob.R 009ffe47b8c239e7c7e0f1331d5ea736 *R/cast.R 6767356bc6b42140767ca1aa1bfab508 *R/coerce.R f72b00930e22e0d7d8ce02b6d85f1e4d *R/compat-lifecycle.R b4acb686a84e6ea18a55408dc5e6ba12 *R/format.R 6dd3a73c15682b8a0dd04515d9ce520f *R/prettyunits.R 52a1a78178c737a22f1149841187bad9 *R/util.R ee8319ef9d1ba02ee6a5eb4a4d8c3d98 *R/zzz.R 7bdd862c347ff2874399f1ab9d9026c0 *README.md 11835976f11cf847cd37841e91a04cbd *man/as.blob.Rd db4f3a3c39e1dbe8921e6c8dec375a54 *man/blob.Rd e5ebd9747daa786fb6a735bc9be0a805 *man/vec_cast.blob.Rd 5932c89be17465583d519b8de50811d5 *man/vec_ptype2.blob.Rd c37a14165e8d4b49908e517ea43960a7 *tests/testthat.R 2b6213f9da53245378ad910526038003 *tests/testthat/blob.txt 9933209090f8600c0557dcedfd526f6d *tests/testthat/helper-deprecate.R 45d06a1de00c8c956dace82519dcb373 *tests/testthat/test-accessors.R 04dab976acf19c9fcf76cf6840c6b0cd *tests/testthat/test-cast.R 0c973b4ea0fee203790190ef73a1c23b *tests/testthat/test-construction.R 895720a1eec014fe4d0388196fb2cfaf *tests/testthat/test-format.R 2ef6c2fb2c7099057657ea8d3e2a89b5 *tests/testthat/test-missing.R