Skip to content

Commit f6d9c25

Browse files
committed
Update for latest rlang check helpers
1 parent 285eb28 commit f6d9c25

File tree

9 files changed

+210
-81
lines changed

9 files changed

+210
-81
lines changed

R/c.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
#' str_c("x", character())
5353
#' paste0("x", character())
5454
str_c <- function(..., sep = "", collapse = NULL) {
55-
check_string(sep, allow_empty = TRUE)
56-
check_string(collapse, allow_null = TRUE, allow_empty = TRUE)
55+
check_string(sep)
56+
check_string(collapse, allow_null = TRUE)
5757

5858
dots <- list(...)
5959
dots <- dots[!map_lgl(dots, is.null)]

R/compat-obj-type.R

Lines changed: 96 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
# Changelog
44
# =========
55
#
6+
# 2022-10-04:
7+
# - `obj_type_friendly(value = TRUE)` now shows numeric scalars
8+
# literally.
9+
# - `stop_friendly_type()` now takes `show_value`, passed to
10+
# `obj_type_friendly()` as the `value` argument.
11+
#
612
# 2022-10-03:
713
# - Added `allow_na` and `allow_null` arguments.
814
# - `NULL` is now backticked.
@@ -34,12 +40,13 @@
3440

3541
#' Return English-friendly type
3642
#' @param x Any R object.
37-
#' @param value Whether to describe the value of `x`.
43+
#' @param value Whether to describe the value of `x`. Special values
44+
#' like `NA` or `""` are always described.
3845
#' @param length Whether to mention the length of vectors and lists.
3946
#' @return A string describing the type. Starts with an indefinite
4047
#' article, e.g. "an integer vector".
4148
#' @noRd
42-
obj_type_friendly <- function(x, value = TRUE, length = FALSE) {
49+
obj_type_friendly <- function(x, value = TRUE) {
4350
if (is_missing(x)) {
4451
return("absent")
4552
}
@@ -59,44 +66,75 @@ obj_type_friendly <- function(x, value = TRUE, length = FALSE) {
5966

6067
n_dim <- length(dim(x))
6168

62-
if (value && !n_dim) {
63-
if (is_na(x)) {
64-
return(switch(
65-
typeof(x),
66-
logical = "`NA`",
67-
integer = "an integer `NA`",
68-
double =
69-
if (is.nan(x)) {
70-
"`NaN`"
71-
} else {
72-
"a numeric `NA`"
69+
if (!n_dim) {
70+
if (!is_list(x) && length(x) == 1) {
71+
if (is_na(x)) {
72+
return(switch(
73+
typeof(x),
74+
logical = "`NA`",
75+
integer = "an integer `NA`",
76+
double =
77+
if (is.nan(x)) {
78+
"`NaN`"
79+
} else {
80+
"a numeric `NA`"
81+
},
82+
complex = "a complex `NA`",
83+
character = "a character `NA`",
84+
.rlang_stop_unexpected_typeof(x)
85+
))
86+
}
87+
88+
show_infinites <- function(x) {
89+
if (x > 0) {
90+
"`Inf`"
91+
} else {
92+
"`-Inf`"
93+
}
94+
}
95+
str_encode <- function(x, width = 30, ...) {
96+
if (nchar(x) > width) {
97+
x <- substr(x, 1, width - 3)
98+
x <- paste0(x, "...")
99+
}
100+
encodeString(x, ...)
101+
}
102+
103+
if (value) {
104+
if (is.numeric(x) && is.infinite(x)) {
105+
return(show_infinites(x))
106+
}
107+
108+
if (is.numeric(x) || is.complex(x)) {
109+
number <- as.character(round(x, 2))
110+
what <- if (is.complex(x)) "the complex number" else "the number"
111+
return(paste(what, number))
112+
}
113+
114+
return(switch(
115+
typeof(x),
116+
logical = if (x) "`TRUE`" else "`FALSE`",
117+
character = {
118+
what <- if (nzchar(x)) "the string" else "the empty string"
119+
paste(what, str_encode(x, quote = "\""))
73120
},
74-
complex = "a complex `NA`",
75-
character = "a character `NA`",
76-
.rlang_stop_unexpected_typeof(x)
77-
))
78-
}
79-
if (length(x) == 1 && !is_list(x)) {
121+
raw = paste("the raw value", as.character(x)),
122+
.rlang_stop_unexpected_typeof(x)
123+
))
124+
}
125+
80126
return(switch(
81127
typeof(x),
82-
logical = if (x) "`TRUE`" else "`FALSE`",
128+
logical = "a logical value",
83129
integer = "an integer",
84-
double =
85-
if (is.infinite(x)) {
86-
if (x > 0) {
87-
"`Inf`"
88-
} else {
89-
"`-Inf`"
90-
}
91-
} else {
92-
"a number"
93-
},
130+
double = if (is.infinite(x)) show_infinites(x) else "a number",
94131
complex = "a complex number",
95-
character = if (nzchar(x)) "a string" else "`\"\"`",
132+
character = if (nzchar(x)) "a string" else "\"\"",
96133
raw = "a raw value",
97134
.rlang_stop_unexpected_typeof(x)
98135
))
99136
}
137+
100138
if (length(x) == 0) {
101139
return(switch(
102140
typeof(x),
@@ -112,19 +150,29 @@ obj_type_friendly <- function(x, value = TRUE, length = FALSE) {
112150
}
113151
}
114152

115-
type <- .rlang_as_friendly_vector_type(typeof(x), n_dim)
153+
vec_type_friendly(x)
154+
}
116155

117-
if (length && !n_dim) {
118-
type <- paste0(type, sprintf(" of length %s", length(x)))
156+
vec_type_friendly <- function(x, length = FALSE) {
157+
if (!is_vector(x)) {
158+
abort("`x` must be a vector.")
119159
}
160+
type <- typeof(x)
161+
n_dim <- length(dim(x))
120162

121-
type
122-
}
163+
add_length <- function(type) {
164+
if (length && !n_dim) {
165+
paste0(type, sprintf(" of length %s", length(x)))
166+
} else {
167+
type
168+
}
169+
}
123170

124-
.rlang_as_friendly_vector_type <- function(type, n_dim) {
125171
if (type == "list") {
126172
if (n_dim < 2) {
127-
return("a list")
173+
return(add_length("a list"))
174+
} else if (is.data.frame(x)) {
175+
return("a data frame")
128176
} else if (n_dim == 2) {
129177
return("a list matrix")
130178
} else {
@@ -151,7 +199,13 @@ obj_type_friendly <- function(x, value = TRUE, length = FALSE) {
151199
} else {
152200
kind <- "array"
153201
}
154-
sprintf(type, kind)
202+
out <- sprintf(type, kind)
203+
204+
if (n_dim >= 2) {
205+
out
206+
} else {
207+
add_length(out)
208+
}
155209
}
156210

157211
.rlang_as_friendly_type <- function(type) {
@@ -222,6 +276,7 @@ obj_type_oo <- function(x) {
222276
#' @param what The friendly expected type as a string. Can be a
223277
#' character vector of expected types, in which case the error
224278
#' message mentions all of them in an "or" enumeration.
279+
#' @param show_value Passed to `value` argument of `obj_type_friendly()`.
225280
#' @param ... Arguments passed to [abort()].
226281
#' @inheritParams args_error_context
227282
#' @noRd
@@ -230,6 +285,7 @@ stop_input_type <- function(x,
230285
...,
231286
allow_na = FALSE,
232287
allow_null = FALSE,
288+
show_value = TRUE,
233289
arg = caller_arg(x),
234290
call = caller_env()) {
235291
# From compat-cli.R
@@ -254,7 +310,7 @@ stop_input_type <- function(x,
254310
"%s must be %s, not %s.",
255311
cli$format_arg(arg),
256312
what,
257-
obj_type_friendly(x)
313+
obj_type_friendly(x, value = show_value)
258314
)
259315

260316
abort(message, ..., call = call, arg = arg)

0 commit comments

Comments
 (0)