| Title: | Composable Runtime Contracts for R |
|---|---|
| Description: | Build reusable validators from small building blocks using the base pipe operator. Define runtime contracts once with 'restrict()' and enforce them anywhere in code. Validators compose naturally, support dependent rules via formulas, and produce clear, path-aware error messages. No DSL, no operator overloading, just idiomatic R. |
| Authors: | Gilles Colling [aut, cre, cph] (ORCID: <https://orcid.org/0000-0003-3070-6066>) |
| Maintainer: | Gilles Colling <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.2 |
| Built: | 2026-05-31 07:00:45 UTC |
| Source: | https://github.com/gcol33/restrictr |
Produces a multi-line text summary suitable for roxygen @details
documentation. Each step appears on its own line as a bullet point.
as_contract_block(x)as_contract_block(x)
x |
a |
A character(1) string with one step per line.
Other core:
as_contract_text(),
fail(),
require_custom(),
restrict()
v <- restrict("x") |> require_numeric(no_na = TRUE) |> require_length(1L) as_contract_block(v)v <- restrict("x") |> require_numeric(no_na = TRUE) |> require_length(1L) as_contract_block(v)
Produces a single-line text summary suitable for roxygen @param
documentation. Use with inline R code in roxygen: `r as_contract_text(validator)`.
as_contract_text(x)as_contract_text(x)
x |
a |
A character(1) string describing the validation contract.
Other core:
as_contract_block(),
fail(),
require_custom(),
restrict()
v <- restrict("x") |> require_numeric(no_na = TRUE) |> require_length(1L) as_contract_text(v)v <- restrict("x") |> require_numeric(no_na = TRUE) |> require_length(1L) as_contract_text(v)
Produces a consistently formatted error message and stops execution.
Intended for use inside custom validation steps created with
require_custom(), so they produce the same structured errors as built-in
steps.
fail(path, message, found = NULL, at = NULL)fail(path, message, found = NULL, at = NULL)
path |
the full path (e.g. |
message |
the specific failure message. |
found |
optional value to show on a |
at |
optional integer positions to show on an |
Format: path: message, with optional Found: and At: lines.
Other core:
as_contract_block(),
as_contract_text(),
require_custom(),
restrict()
## Not run: fail("x", "must be positive", found = -3, at = 2L) # Error: x: must be positive # Found: -3 # At: 2 ## End(Not run)## Not run: fail("x", "must be positive", found = -3, at = 2L) # Error: x: must be positive # Found: -3 # At: 2 ## End(Not run)
Validates that all elements of a numeric value fall within a specified range.
require_between( restriction, lower = -Inf, upper = Inf, exclusive_lower = FALSE, exclusive_upper = FALSE )require_between( restriction, lower = -Inf, upper = Inf, exclusive_lower = FALSE, exclusive_upper = FALSE )
restriction |
a |
lower |
numeric(1) lower bound (default |
upper |
numeric(1) upper bound (default |
exclusive_lower |
logical; if |
exclusive_upper |
logical; if |
The modified restriction object.
Other value checks:
require_negative(),
require_one_of(),
require_positive(),
require_unique()
Validates that the value is character. Optionally checks for NA values.
require_character(restriction, no_na = FALSE)require_character(restriction, no_na = FALSE)
restriction |
a |
no_na |
logical; if |
The modified restriction object.
Other type checks:
require_df(),
require_integer(),
require_logical(),
require_numeric()
Validates that all values in a column fall within a specified range.
require_col_between( restriction, col, lower = -Inf, upper = Inf, exclusive_lower = FALSE, exclusive_upper = FALSE )require_col_between( restriction, col, lower = -Inf, upper = Inf, exclusive_lower = FALSE, exclusive_upper = FALSE )
restriction |
a |
col |
character(1) column name. |
lower |
numeric(1) lower bound (default |
upper |
numeric(1) upper bound (default |
exclusive_lower |
logical; if |
exclusive_upper |
logical; if |
The modified restriction object.
Other column checks:
require_col_character(),
require_col_numeric(),
require_col_one_of()
Validates that a specific column in a data.frame is character. Produces path-aware error messages.
require_col_character(restriction, col, no_na = FALSE)require_col_character(restriction, col, no_na = FALSE)
restriction |
a |
col |
character(1) column name. |
no_na |
logical; if |
The modified restriction object.
Other column checks:
require_col_between(),
require_col_numeric(),
require_col_one_of()
Validates that a specific column in a data.frame is numeric. Produces
path-aware error messages (e.g. newdata$x2: must be numeric).
require_col_numeric(restriction, col, no_na = FALSE, finite = FALSE)require_col_numeric(restriction, col, no_na = FALSE, finite = FALSE)
restriction |
a |
col |
character(1) column name. |
no_na |
logical; if |
finite |
logical; if |
The modified restriction object.
Other column checks:
require_col_between(),
require_col_character(),
require_col_one_of()
Validates that all values in a column are among the allowed values.
require_col_one_of(restriction, col, values)require_col_one_of(restriction, col, values)
restriction |
a |
col |
character(1) column name. |
values |
vector of allowed values. |
The modified restriction object.
Other column checks:
require_col_between(),
require_col_character(),
require_col_numeric()
Allows advanced users to define their own validation step without
growing the package's built-in API surface. The step function receives
(value, name, ctx) and should call fail() on validation failure.
require_custom(restriction, label, fn, deps = character(0L))require_custom(restriction, label, fn, deps = character(0L))
restriction |
a |
label |
character(1) human-readable description for printing. |
fn |
a function with signature |
deps |
character vector of context names this step requires (default: none). |
A new restriction object with the custom step appended.
Other core:
as_contract_block(),
as_contract_text(),
fail(),
restrict()
# Custom step: require all values to be unique require_unique_id <- restrict("id") |> require_custom( label = "must contain unique values", fn = function(value, name, ctx) { dupes <- which(duplicated(value)) if (length(dupes) > 0L) { fail(name, "contains duplicates", at = dupes) } } )# Custom step: require all values to be unique require_unique_id <- restrict("id") |> require_custom( label = "must contain unique values", fn = function(value, name, ctx) { dupes <- which(duplicated(value)) if (length(dupes) > 0L) { fail(name, "contains duplicates", at = dupes) } } )
Validates that the value is a data.frame.
require_df(restriction)require_df(restriction)
restriction |
a |
The modified restriction object.
Other type checks:
require_character(),
require_integer(),
require_logical(),
require_numeric()
Validates that a numeric value contains no Inf, -Inf, or NaN values.
Does not check for NA (use require_no_na() for that).
require_finite(restriction)require_finite(restriction)
restriction |
a |
The modified restriction object.
Other missingness checks:
require_no_na(),
require_not_null()
Validates that a data.frame contains all specified columns.
require_has_cols(restriction, cols)require_has_cols(restriction, cols)
restriction |
a |
cols |
character vector of required column names. |
The modified restriction object.
Other structure checks:
require_length(),
require_length_matches(),
require_length_max(),
require_length_min(),
require_named(),
require_nrow_matches(),
require_nrow_min(),
require_scalar()
Validates that the value contains whole numbers. By default accepts both
integer and numeric types as long as all values are whole
(x == floor(x)). Set strict = TRUE to require the R integer type.
require_integer(restriction, no_na = FALSE, strict = FALSE)require_integer(restriction, no_na = FALSE, strict = FALSE)
restriction |
a |
no_na |
logical; if |
strict |
logical; if |
The modified restriction object.
Other type checks:
require_character(),
require_df(),
require_logical(),
require_numeric()
Validates that the value has exact length n.
require_length(restriction, n)require_length(restriction, n)
restriction |
a |
n |
integer(1) required length. |
The modified restriction object.
Other structure checks:
require_has_cols(),
require_length_matches(),
require_length_max(),
require_length_min(),
require_named(),
require_nrow_matches(),
require_nrow_min(),
require_scalar()
Validates that length(value) equals the result of evaluating a formula.
The formula is evaluated using only explicitly passed context arguments,
plus .value (the validated value) and .name (the restriction name).
require_length_matches(restriction, formula)require_length_matches(restriction, formula)
restriction |
a |
formula |
a one-sided formula (e.g. |
The modified restriction object.
Other structure checks:
require_has_cols(),
require_length(),
require_length_max(),
require_length_min(),
require_named(),
require_nrow_matches(),
require_nrow_min(),
require_scalar()
Validates that the value has at most length n.
require_length_max(restriction, n)require_length_max(restriction, n)
restriction |
a |
n |
integer(1) maximum length. |
The modified restriction object.
Other structure checks:
require_has_cols(),
require_length(),
require_length_matches(),
require_length_min(),
require_named(),
require_nrow_matches(),
require_nrow_min(),
require_scalar()
Validates that the value has at least length n.
require_length_min(restriction, n)require_length_min(restriction, n)
restriction |
a |
n |
integer(1) minimum length. |
The modified restriction object.
Other structure checks:
require_has_cols(),
require_length(),
require_length_matches(),
require_length_max(),
require_named(),
require_nrow_matches(),
require_nrow_min(),
require_scalar()
Validates that the value is logical. Optionally checks for NA values.
require_logical(restriction, no_na = FALSE)require_logical(restriction, no_na = FALSE)
restriction |
a |
no_na |
logical; if |
The modified restriction object.
Other type checks:
require_character(),
require_df(),
require_integer(),
require_numeric()
Validates that the value has names. Useful for named vectors and lists.
require_named(restriction)require_named(restriction)
restriction |
a |
The modified restriction object.
Other structure checks:
require_has_cols(),
require_length(),
require_length_matches(),
require_length_max(),
require_length_min(),
require_nrow_matches(),
require_nrow_min(),
require_scalar()
Validates that all elements are negative. By default uses <= 0
(non-positive); set strict = TRUE for < 0.
require_negative(restriction, strict = FALSE)require_negative(restriction, strict = FALSE)
restriction |
a |
strict |
logical; if |
The modified restriction object.
Other value checks:
require_between(),
require_one_of(),
require_positive(),
require_unique()
Validates that the value contains no NA values. Works on any atomic type.
require_no_na(restriction)require_no_na(restriction)
restriction |
a |
The modified restriction object.
Other missingness checks:
require_finite(),
require_not_null()
Validates that the value is not NULL. Place this step first in the
pipeline when NULL is a possible input.
require_not_null(restriction)require_not_null(restriction)
restriction |
a |
The modified restriction object.
Other missingness checks:
require_finite(),
require_no_na()
Validates that nrow(value) equals the result of evaluating a formula.
The formula is evaluated using only explicitly passed context arguments,
plus .value (the validated value) and .name (the restriction name).
require_nrow_matches(restriction, formula)require_nrow_matches(restriction, formula)
restriction |
a |
formula |
a one-sided formula (e.g. |
The modified restriction object.
Other structure checks:
require_has_cols(),
require_length(),
require_length_matches(),
require_length_max(),
require_length_min(),
require_named(),
require_nrow_min(),
require_scalar()
Validates that a data.frame has at least n rows.
require_nrow_min(restriction, n)require_nrow_min(restriction, n)
restriction |
a |
n |
integer(1) minimum row count. |
The modified restriction object.
Other structure checks:
require_has_cols(),
require_length(),
require_length_matches(),
require_length_max(),
require_length_min(),
require_named(),
require_nrow_matches(),
require_scalar()
Validates that the value is numeric. Optionally checks for NA and non-finite values.
require_numeric(restriction, no_na = FALSE, finite = FALSE)require_numeric(restriction, no_na = FALSE, finite = FALSE)
restriction |
a |
no_na |
logical; if |
finite |
logical; if |
The modified restriction object.
Other type checks:
require_character(),
require_df(),
require_integer(),
require_logical()
Validates that all elements of the value are among the allowed values.
require_one_of(restriction, values)require_one_of(restriction, values)
restriction |
a |
values |
vector of allowed values. |
The modified restriction object.
Other value checks:
require_between(),
require_negative(),
require_positive(),
require_unique()
Validates that all elements are positive. By default uses >= 0
(non-negative); set strict = TRUE for > 0.
require_positive(restriction, strict = FALSE)require_positive(restriction, strict = FALSE)
restriction |
a |
strict |
logical; if |
The modified restriction object.
Other value checks:
require_between(),
require_negative(),
require_one_of(),
require_unique()
Validates that the value has length 1. Rejects NULL, zero-length vectors,
and vectors with more than one element.
require_scalar(restriction)require_scalar(restriction)
restriction |
a |
The modified restriction object.
Other structure checks:
require_has_cols(),
require_length(),
require_length_matches(),
require_length_max(),
require_length_min(),
require_named(),
require_nrow_matches(),
require_nrow_min()
Validates that the value contains no duplicates. Reports the positions of duplicated elements.
require_unique(restriction)require_unique(restriction)
restriction |
a |
The modified restriction object.
Other value checks:
require_between(),
require_negative(),
require_one_of(),
require_positive()
Creates a callable validation object that accumulates checks via the base
pipe operator |>. The resulting object behaves like a function: call it
with a value to validate.
restrict(name)restrict(name)
name |
character(1) name used in error messages (e.g. |
A restriction object (callable function) with no validation steps.
Validators accept value as the first argument, plus context via named
arguments in ... or as a named list in .ctx:
require_pred(out, newdata = df) require_pred(out, .ctx = list(newdata = df))
Named arguments in ... take precedence over .ctx entries with the
same name. If a step declares dependencies (e.g. require_length_matches(~ nrow(newdata))), the validator checks that all required context is present
before running any steps and errors early if not.
Other core:
as_contract_block(),
as_contract_text(),
fail(),
require_custom()
# Define a validator require_positive <- restrict("x") |> require_numeric(no_na = TRUE) |> require_between(lower = 0, exclusive_lower = TRUE) # Use it require_positive(5) # passes silently # Compose with pipe require_score <- restrict("score") |> require_numeric() |> require_length(1L) |> require_between(lower = 0, upper = 100)# Define a validator require_positive <- restrict("x") |> require_numeric(no_na = TRUE) |> require_between(lower = 0, exclusive_lower = TRUE) # Use it require_positive(5) # passes silently # Compose with pipe require_score <- restrict("score") |> require_numeric() |> require_length(1L) |> require_between(lower = 0, upper = 100)