Package 'restrictR'

Title: Composable Runtime Contracts
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 domain-specific language, 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.2.0
Built: 2026-06-29 17:40:05 UTC
Source: https://github.com/gcol33/restrictr

Help Index


Convert a Validator to a Multi-Line Block

Description

Produces a multi-line text summary suitable for roxygen ⁠@details⁠ documentation. Each step appears on its own line as a bullet point.

Usage

as_contract_block(x)

Arguments

x

a restriction object.

Value

A character(1) string with one step per line.

See Also

Other core: as_contract_text(), fail(), is_valid(), require_custom(), restrict(), validation_errors()

Examples

v <- restrict("x") |> require_numeric(no_na = TRUE) |> require_length(1L)
as_contract_block(v)

Convert a Validator to Plain Text

Description

Produces a single-line text summary suitable for roxygen ⁠@param⁠ documentation. Use with inline R code in roxygen: `r as_contract_text(validator)`.

Usage

as_contract_text(x)

Arguments

x

a restriction object.

Value

A character(1) string describing the validation contract.

See Also

Other core: as_contract_block(), fail(), is_valid(), require_custom(), restrict(), validation_errors()

Examples

v <- restrict("x") |> require_numeric(no_na = TRUE) |> require_length(1L)
as_contract_text(v)

Format a Validation Error

Description

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.

Usage

fail(path, message, found = NULL, at = NULL)

Arguments

path

the full path (e.g. "x" or "newdata$x2").

message

the specific failure message.

found

optional value to show on a ⁠Found:⁠ line.

at

optional integer positions to show on an ⁠At:⁠ line.

Details

Format: path: message, with optional ⁠Found:⁠ and ⁠At:⁠ lines.

Value

No return value. Called for its side effect: it signals a classed restrictR_failure condition (an error) carrying path, message, and the optional found and at details.

See Also

Other core: as_contract_block(), as_contract_text(), is_valid(), require_custom(), restrict(), validation_errors()

Examples

# fail() signals an error; wrap in try() to show the formatted message
try(fail("x", "must be positive", found = -3, at = 2L))

Test Whether a Value Satisfies a Validator

Description

Non-throwing predicate: returns TRUE when value passes every step of validator, FALSE otherwise. Use it to branch on validity instead of wrapping a validator call in tryCatch().

Usage

is_valid(validator, value, ...)

Arguments

validator

a restriction object created by restrict().

value

the value to validate.

...

context arguments passed to the validator (e.g. newdata = df), the same as a direct validator call.

Details

Like validation_errors(), only validation failures are caught; a missing context dependency still raises so a calling mistake is not mistaken for invalid data.

Value

A length-1 logical.

See Also

validation_errors() for the failure messages.

Other core: as_contract_block(), as_contract_text(), fail(), require_custom(), restrict(), validation_errors()

Examples

v <- restrict("x") |> require_numeric(no_na = TRUE)
is_valid(v, 1:5)        # TRUE
is_valid(v, c(1, NA))   # FALSE

Require Value in Range

Description

Validates that all elements of a numeric value fall within a specified range.

Usage

require_between(
  restriction,
  lower = -Inf,
  upper = Inf,
  exclusive_lower = FALSE,
  exclusive_upper = FALSE
)

Arguments

restriction

a restriction object.

lower

numeric(1) lower bound (default -Inf).

upper

numeric(1) upper bound (default Inf).

exclusive_lower

logical; if TRUE, lower bound is exclusive.

exclusive_upper

logical; if TRUE, upper bound is exclusive.

Details

Non-numeric input fails with a type error. NA elements are skipped; chain require_no_na() to reject them.

Value

The modified restriction object.

See Also

Other value checks: require_negative(), require_one_of(), require_positive(), require_unique()


Require Character Type

Description

Validates that the value is character. Optionally checks for NA values.

Usage

require_character(restriction, no_na = FALSE)

Arguments

restriction

a restriction object.

no_na

logical; if TRUE, rejects NA values.

Value

The modified restriction object.

See Also

Other type checks: require_class(), require_df(), require_integer(), require_logical(), require_numeric()


Require a Specific Class

Description

Validates that the value belongs to a given class. One verb covers the types without a dedicated check, including factor, Date, POSIXct, list, and fitted-model objects such as lm.

Usage

require_class(restriction, class, exact = FALSE)

Arguments

restriction

a restriction object.

class

character(1) class name to require.

exact

logical; if TRUE, requires class(value)[1] to equal class exactly. If FALSE (default), tests inheritance with inherits(), so a subclass passes.

Value

The modified restriction object.

See Also

Other type checks: require_character(), require_df(), require_integer(), require_logical(), require_numeric()

Examples

restrict("d") |> require_class("Date")
restrict("f") |> require_class("factor")
restrict("model") |> require_class("lm")

Require Column Values in Range

Description

Validates that all values in a column fall within a specified range.

Usage

require_col_between(
  restriction,
  col,
  lower = -Inf,
  upper = Inf,
  exclusive_lower = FALSE,
  exclusive_upper = FALSE
)

Arguments

restriction

a restriction object.

col

character(1) column name.

lower

numeric(1) lower bound (default -Inf).

upper

numeric(1) upper bound (default Inf).

exclusive_lower

logical; if TRUE, lower bound is exclusive.

exclusive_upper

logical; if TRUE, upper bound is exclusive.

Details

A non-numeric column fails with a type error. NA elements are skipped; use require_col_numeric(col, no_na = TRUE) to reject them.

Value

The modified restriction object.

See Also

Other column checks: require_col_character(), require_col_numeric(), require_col_one_of()


Require Character Column

Description

Validates that a specific column in a data.frame is character. Produces path-aware error messages.

Usage

require_col_character(restriction, col, no_na = FALSE)

Arguments

restriction

a restriction object.

col

character(1) column name.

no_na

logical; if TRUE, rejects NA values in the column.

Value

The modified restriction object.

See Also

Other column checks: require_col_between(), require_col_numeric(), require_col_one_of()


Require Numeric Column

Description

Validates that a specific column in a data.frame is numeric. Produces path-aware error messages (e.g. ⁠newdata$x2: must be numeric⁠).

Usage

require_col_numeric(restriction, col, no_na = FALSE, finite = FALSE)

Arguments

restriction

a restriction object.

col

character(1) column name.

no_na

logical; if TRUE, rejects NA values in the column.

finite

logical; if TRUE, rejects non-finite values in the column.

Value

The modified restriction object.

See Also

Other column checks: require_col_between(), require_col_character(), require_col_one_of()


Require Column Values from a Set

Description

Validates that all values in a column are among the allowed values.

Usage

require_col_one_of(restriction, col, values)

Arguments

restriction

a restriction object.

col

character(1) column name.

values

vector of allowed values.

Details

NA elements are skipped; use require_col_character(col, no_na = TRUE) (or the matching column type check) to reject them.

Value

The modified restriction object.

See Also

Other column checks: require_col_between(), require_col_character(), require_col_numeric()


Create a Custom Validation Step

Description

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.

Usage

require_custom(restriction, label, fn, deps = character(0L))

Arguments

restriction

a restriction object.

label

character(1) human-readable description for printing.

fn

a function with signature ⁠function(value, name, ctx)⁠ that calls fail() on validation failure.

deps

character vector of context names this step requires (default: none).

Value

A new restriction object with the custom step appended.

See Also

Other core: as_contract_block(), as_contract_text(), fail(), is_valid(), restrict(), validation_errors()

Examples

# 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)
      }
    }
  )

Require a Data Frame

Description

Validates that the value is a data.frame.

Usage

require_df(restriction)

Arguments

restriction

a restriction object.

Value

The modified restriction object.

See Also

Other type checks: require_character(), require_class(), require_integer(), require_logical(), require_numeric()


Require Finite Values

Description

Validates that a numeric value contains no Inf, -Inf, or NaN values. Does not check for NA (use require_no_na() for that).

Usage

require_finite(restriction)

Arguments

restriction

a restriction object.

Value

The modified restriction object.

See Also

Other missingness checks: require_no_na(), require_not_null()


Require Specific Columns

Description

Validates that a data.frame contains all specified columns.

Usage

require_has_cols(restriction, cols)

Arguments

restriction

a restriction object.

cols

character vector of required column names.

Value

The modified restriction object.

See Also

Other structure checks: require_length(), require_length_matches(), require_length_max(), require_length_min(), require_named(), require_nrow_matches(), require_nrow_min(), require_scalar()


Require Integer Values

Description

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.

Usage

require_integer(restriction, no_na = FALSE, strict = FALSE)

Arguments

restriction

a restriction object.

no_na

logical; if TRUE, rejects NA values.

strict

logical; if TRUE, requires R integer type. If FALSE (default), accepts any numeric value that is a whole number.

Value

The modified restriction object.

See Also

Other type checks: require_character(), require_class(), require_df(), require_logical(), require_numeric()


Require Specific Length

Description

Validates that the value has exact length n.

Usage

require_length(restriction, n)

Arguments

restriction

a restriction object.

n

integer(1) required length.

Value

The modified restriction object.

See Also

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()


Require Length Matching an Expression

Description

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).

Usage

require_length_matches(restriction, formula)

Arguments

restriction

a restriction object.

formula

a one-sided formula (e.g. ~ nrow(newdata)).

Value

The modified restriction object.

See Also

Other structure checks: require_has_cols(), require_length(), require_length_max(), require_length_min(), require_named(), require_nrow_matches(), require_nrow_min(), require_scalar()


Require Maximum Length

Description

Validates that the value has at most length n.

Usage

require_length_max(restriction, n)

Arguments

restriction

a restriction object.

n

integer(1) maximum length.

Value

The modified restriction object.

See Also

Other structure checks: require_has_cols(), require_length(), require_length_matches(), require_length_min(), require_named(), require_nrow_matches(), require_nrow_min(), require_scalar()


Require Minimum Length

Description

Validates that the value has at least length n.

Usage

require_length_min(restriction, n)

Arguments

restriction

a restriction object.

n

integer(1) minimum length.

Value

The modified restriction object.

See Also

Other structure checks: require_has_cols(), require_length(), require_length_matches(), require_length_max(), require_named(), require_nrow_matches(), require_nrow_min(), require_scalar()


Require Logical Type

Description

Validates that the value is logical. Optionally checks for NA values.

Usage

require_logical(restriction, no_na = FALSE)

Arguments

restriction

a restriction object.

no_na

logical; if TRUE, rejects NA values.

Value

The modified restriction object.

See Also

Other type checks: require_character(), require_class(), require_df(), require_integer(), require_numeric()


Require Named Value

Description

Validates that the value is fully named: every element has a non-empty, non-NA name. A partially-named value (e.g. c(a = 1, 2)) fails and the positions of the unnamed elements are reported.

Usage

require_named(restriction)

Arguments

restriction

a restriction object.

Value

The modified restriction object.

See Also

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()


Require Negative Values

Description

Validates that all elements are negative. By default uses ⁠<= 0⁠ (non-positive); set strict = TRUE for ⁠< 0⁠.

Usage

require_negative(restriction, strict = FALSE)

Arguments

restriction

a restriction object.

strict

logical; if TRUE, requires ⁠< 0⁠. If FALSE (default), requires ⁠<= 0⁠.

Details

Non-numeric input fails with a type error. NA elements are skipped; chain require_no_na() to reject them.

Value

The modified restriction object.

See Also

Other value checks: require_between(), require_one_of(), require_positive(), require_unique()


Require No NA Values

Description

Validates that the value contains no NA values. Works on any atomic type.

Usage

require_no_na(restriction)

Arguments

restriction

a restriction object.

Value

The modified restriction object.

See Also

Other missingness checks: require_finite(), require_not_null()


Require Non-NULL Value

Description

Validates that the value is not NULL. Place this step first in the pipeline when NULL is a possible input.

Usage

require_not_null(restriction)

Arguments

restriction

a restriction object.

Value

The modified restriction object.

See Also

Other missingness checks: require_finite(), require_no_na()


Require Row Count Matching an Expression

Description

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).

Usage

require_nrow_matches(restriction, formula)

Arguments

restriction

a restriction object.

formula

a one-sided formula (e.g. ~ nrow(reference)).

Value

The modified restriction object.

See Also

Other structure checks: require_has_cols(), require_length(), require_length_matches(), require_length_max(), require_length_min(), require_named(), require_nrow_min(), require_scalar()


Require Minimum Number of Rows

Description

Validates that a data.frame has at least n rows.

Usage

require_nrow_min(restriction, n)

Arguments

restriction

a restriction object.

n

integer(1) minimum row count.

Value

The modified restriction object.

See Also

Other structure checks: require_has_cols(), require_length(), require_length_matches(), require_length_max(), require_length_min(), require_named(), require_nrow_matches(), require_scalar()


Require Numeric Type

Description

Validates that the value is numeric. Optionally checks for NA and non-finite values.

Usage

require_numeric(restriction, no_na = FALSE, finite = FALSE)

Arguments

restriction

a restriction object.

no_na

logical; if TRUE, rejects NA values.

finite

logical; if TRUE, rejects Inf/-Inf/NaN.

Value

The modified restriction object.

See Also

Other type checks: require_character(), require_class(), require_df(), require_integer(), require_logical()


Require Value from a Set

Description

Validates that all elements of the value are among the allowed values.

Usage

require_one_of(restriction, values)

Arguments

restriction

a restriction object.

values

vector of allowed values.

Details

NA elements are skipped; chain require_no_na() to reject them.

Value

The modified restriction object.

See Also

Other value checks: require_between(), require_negative(), require_positive(), require_unique()


Require Positive Values

Description

Validates that all elements are positive. By default uses ⁠>= 0⁠ (non-negative); set strict = TRUE for ⁠> 0⁠.

Usage

require_positive(restriction, strict = FALSE)

Arguments

restriction

a restriction object.

strict

logical; if TRUE, requires ⁠> 0⁠. If FALSE (default), requires ⁠>= 0⁠.

Details

Non-numeric input fails with a type error. NA elements are skipped; chain require_no_na() to reject them.

Value

The modified restriction object.

See Also

Other value checks: require_between(), require_negative(), require_one_of(), require_unique()


Require Scalar Value

Description

Validates that the value has length 1. Rejects NULL, zero-length vectors, and vectors with more than one element.

Usage

require_scalar(restriction)

Arguments

restriction

a restriction object.

Value

The modified restriction object.

See Also

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()


Require Unique Values

Description

Validates that the value contains no duplicates. Reports the positions of duplicated elements.

Usage

require_unique(restriction)

Arguments

restriction

a restriction object.

Value

The modified restriction object.

See Also

Other value checks: require_between(), require_negative(), require_one_of(), require_positive()


Create a Composable Validator

Description

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.

Usage

restrict(name)

Arguments

name

character(1) name used in error messages (e.g. "newdata").

Value

A restriction object (callable function) with no validation steps.

Calling convention

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.

By default a validator is fail-fast: the first failing step stops with its error. Pass .on_fail = "all" to run every step and report all violations in one aggregated error:

require_pred(out, .on_fail = "all")

For a non-throwing result, use is_valid() or validation_errors().

See Also

Other core: as_contract_block(), as_contract_text(), fail(), is_valid(), require_custom(), validation_errors()

Examples

# 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)

Collect Validation Errors Without Throwing

Description

Runs a validator against a value and returns the validation messages instead of raising an error. Every step is checked (as with .on_fail = "all"), so all violations are reported in one pass.

Usage

validation_errors(validator, value, ...)

Arguments

validator

a restriction object created by restrict().

value

the value to validate.

...

context arguments passed to the validator (e.g. newdata = df), the same as a direct validator call.

Details

Only validation failures are caught. A usage error, such as a missing context dependency declared by a formula step, still propagates so the calling mistake is not silently reported as invalid data.

Value

A character vector of failure messages, or character(0) if the value satisfies every step. Each element is the full path-aware message for one failing step.

See Also

is_valid() for a logical predicate.

Other core: as_contract_block(), as_contract_text(), fail(), is_valid(), require_custom(), restrict()

Examples

v <- restrict("x") |> require_numeric() |> require_positive()
validation_errors(v, 5)       # character(0)
validation_errors(v, c(-1))   # one message