Skip to content

Commit b648916

Browse files
committed
Update error msg
1 parent ae7bbf6 commit b648916

File tree

4 files changed

+25
-9
lines changed

4 files changed

+25
-9
lines changed

R/base-model.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ print.typewriter <- function(x, ...) {
219219
check_assignment <- function(x, name, value) {
220220
field <- model_fields(x)[[name]]
221221
check_type <- rlang::as_function(field$fn)
222-
error_msg <- ifelse(is_not_null(field$error_msg), field$error_msg, get_fn_text(check_type))
222+
error_msg <- ifelse(is_not_null(field$error_msg), glue::glue(field$error_msg), get_fn_text(check_type))
223223
if (!check_type(value)) {
224224
stop(paste0("Type check failed.\n", error_msg))
225225
}

R/errors.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ get_fn_text <- function(fn) {
1010
# ---
1111
#' @importFrom utils capture.output str
1212
create_type_check_error_message <- function(error) {
13+
name <- error$name
1314
value <- error$value
1415
value_text <- paste0(capture.output(str(value)), collapse = "\n")
1516
fn <- error$type_check_fn

R/types.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ create_model_field <- function(
4848
base_fn <- is_logical
4949
}
5050

51-
error_msg <- paste("value of '{error$name}' must be of type", dtype)
51+
error_msg <- paste("value of '{name}' must be of type", dtype)
5252
check_type <- base_fn
5353
if (is_not_null(n)) {
5454
error_msg <- paste0(error_msg, "(", n, ")")

vignettes/typewriter.Rmd

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ knitr::opts_chunk$set(
1818
library(typewriter)
1919
```
2020

21-
The goal of typewriter is to add type safety to your R code and it is inspired by [Pydantic](https://docs.pydantic.dev/). Under the hood, it mainly uses base R functions to keep its dependencies as low as possible. It lets you
21+
The goal of typewriter is to add type safety to your R code. Under the hood, it mainly uses base R functions to keep its dependencies as low as possible. It lets you
2222

2323
* add types checks to your function arguments with `check_args()`
2424
* create typed structures with `typed_struct()` and `base_model()`
@@ -87,17 +87,26 @@ Person <- typed_struct(
8787
name = "character",
8888
age = "integer"
8989
)
90+
91+
# R, alternate syntax
92+
Person <- typed_struct(
93+
name = character(),
94+
age = integer()
95+
)
9096
```
9197

9298
A typed structure could be used as input for a function:
9399

94100
```{r}
95101
say_hello_to <- function(person) {
102+
stopifnot(inherits(person, "Person"))
96103
paste("Hello", person$name, "you are", person$age, "years old!")
97104
}
98105
99106
hanna <- Person(name = "Hanna", age = 10L)
100107
say_hello_to(hanna)
108+
109+
try(say_hello_to(list(name = "Peter", age = 20L)))
101110
```
102111

103112
You can also use it to validate a data frame:
@@ -114,25 +123,31 @@ df$id <- 1:2
114123
try(Person(df))
115124
```
116125

117-
A type can also be described as a function that takes the value to be validated as its only arguments and returns `TRUE` in case of success:
126+
A type can also be defined as a function that takes the value to be validated as its only argument and returns `TRUE` in case of success:
118127

119128
```{r}
120129
my_type <- typed_struct(
121130
a_number = is.integer,
122-
some_text = is.character
131+
some_text = is.character,
132+
# Add a range check to y
133+
y = function(y) {
134+
is.integer(y) & y > 1 & y < 10
135+
}
123136
)
124137
125138
obj <- my_type(
126139
a_number = 1:2,
127-
some_text = "typewriter"
140+
some_text = "typewriter",
141+
y = 5L
128142
)
129143
130144
obj
131145
132146
try(
133147
my_type(
134-
a_number = NULL,
135-
some_text = "typewriter"
148+
a_number = 1L,
149+
some_text = "typewriter",
150+
y = 1L
136151
)
137152
)
138153
```
@@ -174,7 +189,7 @@ As you can see in the example above you can also check the length of the value b
174189

175190
### The `base_model()` function
176191

177-
Under the hood `typed_struct()` and `check_args()` uses `base_model()` that got its name from [Pydantic's](https://docs.pydantic.dev/) `BaseModel` class. It gives you further options like validating your inputs before the assignment:
192+
Under the hood `typed_struct()` and `check_args()` use `base_model()` that got its name from [Pydantic's](https://docs.pydantic.dev/) `BaseModel` class. It gives you further options like validating your inputs before the assignment:
178193

179194
```{r}
180195
my_model <- base_model(

0 commit comments

Comments
 (0)