| Title: | Schema Inference, Editing, and Validation with 'checkmate' |
|---|---|
| Description: | Provides a compact schema domain-specific language for inferring, editing, and validating R data structures with 'checkmate' checks. Schemas can be serialized to and restored from JSON for storage and review. A generated standalone bundle supports vendoring the schema tools into other R packages. |
| Authors: | Hongyuan Jia [aut, cre, cph] (ORCID: <https://orcid.org/0000-0002-0075-8183>) |
| Maintainer: | Hongyuan Jia <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.1 |
| Built: | 2026-06-07 18:04:31 UTC |
| Source: | https://github.com/hongyuanjia/schemate |
Add a schema definition
schema_add_def(x, name, value, overwrite = FALSE)schema_add_def(x, name, value, overwrite = FALSE)
x |
A |
name |
Definition name to add. |
value |
Schema fragment using the same list syntax accepted by
|
overwrite |
Logical flag indicating whether an existing definition of the same name should be replaced. |
A modified SchemaDoc.
schema <- schema_doc(schema_check("string")) schema <- schema_add_def(schema, "text", schema_check("string")) schema names(as.list(schema)$`$defs`)schema <- schema_doc(schema_check("string")) schema <- schema_add_def(schema, "text", schema_check("string")) schema names(as.list(schema)$`$defs`)
Add a field schema to a container node
schema_add_field(x, name, field, path = "$", overwrite = FALSE)schema_add_field(x, name, field, path = "$", overwrite = FALSE)
x |
A |
name |
Field name to add. |
field |
Schema fragment using the same list syntax accepted by
|
path |
Path to the target container node. Use |
overwrite |
Logical flag indicating whether an existing field of the same name should be replaced. |
A modified SchemaDoc.
schema <- schema_doc(list(check = list(kind = "list"))) schema schema <- schema_add_field(schema, "id", schema_check("int", lower = 1)) schema schema_validate(schema, list(id = 1L), mode = "test")schema <- schema_doc(list(check = list(kind = "list"))) schema schema <- schema_add_field(schema, "id", schema_check("int", lower = 1)) schema schema_validate(schema, list(id = 1L), mode = "test")
Add a schema group to a container node
schema_add_group(x, group, path = "$")schema_add_group(x, group, path = "$")
x |
A |
group |
Schema group fragment using the same list syntax accepted by
|
path |
Path to the target container node. Use |
A modified SchemaDoc.
schema <- schema_doc(list(check = list(kind = "list"))) schema schema <- schema_add_group(schema, schema_group(c("x", "y"), schema_check("number"))) schema schema_validate(schema, list(x = 1, y = 2), mode = "test")schema <- schema_doc(list(check = list(kind = "list"))) schema schema <- schema_add_group(schema, schema_group(c("x", "y"), schema_check("number"))) schema schema_validate(schema, list(x = 1, y = 2), mode = "test")
Add a position schema to an unnamed container node
schema_add_position(x, index, value, path = "$")schema_add_position(x, index, value, path = "$")
x |
A |
index |
1-based insertion index. |
value |
Schema fragment using the same list syntax accepted by
|
path |
Path to the target unnamed container node. Use |
A modified SchemaDoc.
schema <- schema_doc(list( check = list(kind = "list"), keys = list(type = "unnamed") )) schema <- schema_add_position(schema, 1, schema_check("string")) schema <- schema_add_position(schema, 2, schema_check("int")) schema schema_validate(schema, list("a", 1L), mode = "test")schema <- schema_doc(list( check = list(kind = "list"), keys = list(type = "unnamed") )) schema <- schema_add_position(schema, 1, schema_check("string")) schema <- schema_add_position(schema, 2, schema_check("int")) schema schema_validate(schema, list("a", 1L), mode = "test")
all schema combinator fragmentCreate an all schema combinator fragment
schema_all(..., description = NULL)schema_all(..., description = NULL)
... |
Branch schema fragments. |
description |
Optional node description. |
A raw schema fragment accepted by schema_doc() and schema edit verbs.
schema <- schema_doc(schema_all( schema_check("string"), schema_check("string", min.chars = 1) )) schema schema_validate(schema, "ok", mode = "test")schema <- schema_doc(schema_all( schema_check("string"), schema_check("string", min.chars = 1) )) schema schema_validate(schema, "ok", mode = "test")
any schema combinator fragmentCreate an any schema combinator fragment
schema_any(..., description = NULL)schema_any(..., description = NULL)
... |
Branch schema fragments. |
description |
Optional node description. |
A raw schema fragment accepted by schema_doc() and schema edit verbs.
schema <- schema_doc(schema_any(schema_check("int"), schema_check("string"))) schema schema_validate(schema, "ok", mode = "test")schema <- schema_doc(schema_any(schema_check("int"), schema_check("string"))) schema schema_validate(schema, "ok", mode = "test")
schema_check() creates a raw schema fragment with a check operator. The
helper performs only lightweight structural validation; semantic validation of
kind and check arguments is handled by schema_doc() and schema edit verbs.
schema_check(kind, ..., description = NULL)schema_check(kind, ..., description = NULL)
kind |
Check kind string. |
... |
Additional named checkmate arguments stored inside |
description |
Optional node description. |
A raw schema fragment accepted by schema_doc() and schema edit verbs.
schema_check("string", min.chars = 1) schema <- schema_doc(schema_check("string", min.chars = 1)) schemaschema_check("string", min.chars = 1) schema <- schema_doc(schema_check("string", min.chars = 1)) schema
schema_compact() simplifies schema documents produced by inference or
hand-authoring. It can merge observed array element alternatives and group
sibling fields that share identical schemas.
schema_compact(x, arrays = TRUE, groups = TRUE)schema_compact(x, arrays = TRUE, groups = TRUE)
x |
A |
arrays |
Whether to merge compatible |
groups |
Whether to combine sibling fields with identical schemas into
|
A compacted SchemaDoc.
schema <- schema_infer( list(items = list(list(id = 1L, name = "a"), list(id = 2L, label = "b"))), keys = "named", arrays = "rest" ) schema schema_compact(schema)schema <- schema_infer( list(items = list(list(id = 1L, name = "a"), list(id = 2L, label = "b"))), keys = "named", arrays = "rest" ) schema schema_compact(schema)
Delete a schema definition
schema_del_def(x, name, missing = "error")schema_del_def(x, name, missing = "error")
x |
A |
name |
Definition name to remove. |
missing |
Missing-target behavior. Use |
A modified SchemaDoc.
schema <- schema_doc(schema_check("string")) schema <- schema_add_def(schema, "text", schema_check("string")) schema <- schema_del_def(schema, "text") schema as.list(schema)$`$defs`schema <- schema_doc(schema_check("string")) schema <- schema_add_def(schema, "text", schema_check("string")) schema <- schema_del_def(schema, "text") schema as.list(schema)$`$defs`
Delete a field schema from a container node
schema_del_field(x, name, path = "$", missing = "error")schema_del_field(x, name, path = "$", missing = "error")
x |
A |
name |
Field name to remove. |
path |
Path to the target container node. Use |
missing |
Missing-target behavior. Use |
A modified SchemaDoc.
schema <- schema_doc(list(check = list(kind = "list"))) schema schema <- schema_add_field(schema, "id", schema_check("int")) schema schema <- schema_del_field(schema, "id") schemaschema <- schema_doc(list(check = list(kind = "list"))) schema schema <- schema_add_field(schema, "id", schema_check("int")) schema schema <- schema_del_field(schema, "id") schema
Delete a schema group from a container node
schema_del_group(x, index, path = "$", missing = "error")schema_del_group(x, index, path = "$", missing = "error")
x |
A |
index |
1-based group index to remove. |
path |
Path to the target container node. Use |
missing |
Missing-target behavior. Use |
A modified SchemaDoc.
schema <- schema_doc(list( check = list(kind = "list"), groups = list(schema_group(c("x", "y"), schema_check("number"))) )) schema schema_del_group(schema, 1)schema <- schema_doc(list( check = list(kind = "list"), groups = list(schema_group(c("x", "y"), schema_check("number"))) )) schema schema_del_group(schema, 1)
Delete a schema node keys rule
schema_del_keys(x, path = "$", missing = "error")schema_del_keys(x, path = "$", missing = "error")
x |
A |
path |
Path to the target schema node. Use |
missing |
Missing-target behavior. Use |
A modified SchemaDoc.
schema <- schema_doc(list(check = list(kind = "list"), keys = list(type = "named"))) schema <- schema_del_keys(schema) schema as.list(schema)$keysschema <- schema_doc(list(check = list(kind = "list"), keys = list(type = "named"))) schema <- schema_del_keys(schema) schema as.list(schema)$keys
Delete a position schema from an unnamed container node
schema_del_position(x, index, path = "$", missing = "error")schema_del_position(x, index, path = "$", missing = "error")
x |
A |
index |
1-based position index to remove. |
path |
Path to the target unnamed container node. Use |
missing |
Missing-target behavior. Use |
A modified SchemaDoc.
schema <- schema_doc(list(check = list(kind = "list"), keys = list(type = "unnamed"))) schema <- schema_add_position(schema, 1, schema_check("string")) schema <- schema_del_position(schema, 1) schema as.list(schema)$positionsschema <- schema_doc(list(check = list(kind = "list"), keys = list(type = "unnamed"))) schema <- schema_add_position(schema, 1, schema_check("string")) schema <- schema_del_position(schema, 1) schema as.list(schema)$positions
Delete a container rest schema
schema_del_rest(x, path = "$", missing = "error")schema_del_rest(x, path = "$", missing = "error")
x |
A |
path |
Path to the target container node. Use |
missing |
Missing-target behavior. Use |
A modified SchemaDoc.
schema <- schema_doc(list(check = list(kind = "list"))) schema <- schema_set_rest(schema, schema_check("string")) schema <- schema_del_rest(schema) schema as.list(schema)$restschema <- schema_doc(list(check = list(kind = "list"))) schema <- schema_set_rest(schema, schema_check("string")) schema <- schema_del_rest(schema) schema as.list(schema)$rest
schema_doc() parses a schema DSL list into a schemate schema document
object.
schema_doc(x, path = NULL)schema_doc(x, path = NULL)
x |
A schema DSL list or an existing schemate schema document. |
path |
Optional source path stored as runtime metadata. |
Normal users usually create schema documents with schema_infer(),
schema_read(), or the edit helpers. Use schema_doc() when you are
hand-authoring a schema as an R list.
A schemate schema document object.
doc <- schema_doc(list(check = list(kind = "string", min.chars = 1))) doc schema_validate(doc, "ok") schema_validate(doc, 1L, mode = "check")doc <- schema_doc(list(check = list(kind = "string", min.chars = 1))) doc schema_validate(doc, "ok") schema_validate(doc, 1L, mode = "check")
schema_flatten() converts a schema document, raw schema DSL list, or flat
runtime schema node into a SchemaFlat. Reuse the flattened schema when
validating many inputs against the same schema.
schema_flatten(x)schema_flatten(x)
x |
A schema document, raw schema DSL list, |
A flattened SchemaFlat.
schema <- schema_doc(list( check = list(kind = "list"), fields = list(id = list(check = list(kind = "int", lower = 1))) )) flat <- schema_flatten(schema) schema_validate(flat, list(id = 1L), mode = "test")schema <- schema_doc(list( check = list(kind = "list"), fields = list(id = list(check = list(kind = "int", lower = 1))) )) flat <- schema_flatten(schema) schema_validate(flat, list(id = 1L), mode = "test")
Create a schema group fragment
schema_group(names, value, description = NULL)schema_group(names, value, description = NULL)
names |
Field names covered by the group. |
value |
Schema node fragment containing exactly one primary operator. |
description |
Optional group description. |
A raw schema group fragment accepted in a schema document groups
list or by schema_add_group().
schema <- schema_doc(list( check = list(kind = "list"), groups = list(schema_group(c("x", "y"), schema_check("number"))) )) schema schema_validate(schema, list(x = 1, y = 2), mode = "test")schema <- schema_doc(list( check = list(kind = "list"), groups = list(schema_group(c("x", "y"), schema_check("number"))) )) schema schema_validate(schema, list(x = 1, y = 2), mode = "test")
schema_infer() builds a SchemaDoc from example data using conservative,
structural inference only. It infers base/container check kinds and nested
field structure, but does not guess higher-level authoring constructs such as
$defs, $ref, keys, groups, or combinators.
schema_infer( x, version = NULL, keys = c("none", "named", "required", "exact"), arrays = c("none", "rest") )schema_infer( x, version = NULL, keys = c("none", "named", "required", "exact"), arrays = c("none", "rest") )
x |
Example data to infer from. |
version |
Optional schema document version string. |
keys |
Strategy for inferring optional |
arrays |
Strategy for inferring unnamed lists. Use |
To parse an existing schema DSL document, use schema_doc() or
schema_read() instead.
A SchemaDoc inferred from x.
payload <- list(items = list(list(id = 1L), list(id = 2L))) schema_infer(payload, keys = "named", arrays = "rest")payload <- list(items = list(list(id = 1L), list(id = 2L))) schema_infer(payload, keys = "named", arrays = "rest")
schema_modify_where() modifies every schema node matched by where.
schema_replace_where() is a convenience wrapper that replaces all matched
nodes with the same schema fragment.
schema_modify_where(x, where, fn, defs = TRUE, missing = "ignore") schema_replace_where(x, where, value, defs = TRUE, missing = "ignore")schema_modify_where(x, where, fn, defs = TRUE, missing = "ignore") schema_replace_where(x, where, value, defs = TRUE, missing = "ignore")
x |
A schema document or raw schema DSL list. |
where |
Predicate function with signature |
fn |
Function with signature |
defs |
Whether to include root |
missing |
Missing-match behavior. Use |
value |
Replacement schema fragment or |
Batch edits operate on logical paths. Editing every path inside a grouped
schema field preserves the group when the replacement targets are structurally
equivalent; partial edits or differing replacement targets split the group
into per-field bindings. If where matches both a node and one of its
descendants in the same call, the edit errors and asks you to narrow the
selector.
A modified SchemaDoc.
schema <- schema_compact(schema_infer(list( issued = list(`date-parts` = list(list(2024L))), created = list(`date-parts` = list(list(2024L))) ), arrays = "rest")) schema <- schema_add_def(schema, "year", schema_check("int", lower = 0)) schema schema_find(schema, schema_where_path("(^|\\$)`date-parts`\\$rest$")) schema <- schema_replace_where( schema, schema_where_path("(^|\\$)`date-parts`\\$rest$"), schema_ref("year") ) schemaschema <- schema_compact(schema_infer(list( issued = list(`date-parts` = list(list(2024L))), created = list(`date-parts` = list(list(2024L))) ), arrays = "rest")) schema <- schema_add_def(schema, "year", schema_check("int", lower = 0)) schema schema_find(schema, schema_where_path("(^|\\$)`date-parts`\\$rest$")) schema <- schema_replace_where( schema, schema_where_path("(^|\\$)`date-parts`\\$rest$"), schema_ref("year") ) schema
not schema combinator fragmentCreate a not schema combinator fragment
schema_not(branch, description = NULL)schema_not(branch, description = NULL)
branch |
Branch schema fragment. |
description |
Optional node description. |
A raw schema fragment accepted by schema_doc() and schema edit verbs.
schema <- schema_doc(schema_not(schema_check("null"))) schema schema_validate(schema, "ok", mode = "test")schema <- schema_doc(schema_not(schema_check("null"))) schema schema_validate(schema, "ok", mode = "test")
one schema combinator fragmentCreate a one schema combinator fragment
schema_one(..., description = NULL)schema_one(..., description = NULL)
... |
Branch schema fragments. |
description |
Optional node description. |
A raw schema fragment accepted by schema_doc() and schema edit verbs.
schema <- schema_doc(schema_one(schema_check("int"), schema_check("string"))) schema schema_validate(schema, "ok", mode = "test")schema <- schema_doc(schema_one(schema_check("int"), schema_check("string"))) schema schema_validate(schema, "ok", mode = "test")
schema_paths() lists editable logical schema paths. schema_find() returns
paths whose schema node satisfies a predicate.
schema_paths(x, defs = TRUE) schema_find(x, where, defs = TRUE)schema_paths(x, defs = TRUE) schema_find(x, where, defs = TRUE)
x |
A schema document or raw schema DSL list. |
defs |
Whether to include root |
where |
Predicate function with signature |
Logical paths describe fields as users see them in the validated data. Grouped fields are expanded to one path per field.
A character vector of schema paths.
schema <- schema_compact(schema_infer(list( issued = list(`date-parts` = list(list(2024L))), created = list(`date-parts` = list(list(2024L))) ), arrays = "rest")) schema schema_find(schema, schema_where_path("(^|\\$)`date-parts`\\$rest$")) schema_find(schema, schema_where_check("int"))schema <- schema_compact(schema_infer(list( issued = list(`date-parts` = list(list(2024L))), created = list(`date-parts` = list(list(2024L))) ), arrays = "rest")) schema schema_find(schema, schema_where_path("(^|\\$)`date-parts`\\$rest$")) schema_find(schema, schema_where_check("int"))
schema_ref() creates a local $defs reference fragment. name may be
either a bare definition name such as "text" or a local ref string of the
form "#/$defs/text".
schema_ref(name, description = NULL)schema_ref(name, description = NULL)
name |
Definition name or local |
description |
Optional node description. |
A raw schema fragment accepted by schema_doc() and schema edit verbs.
schema <- schema_doc(list( `$defs` = list(text = schema_check("string")), `$ref` = "#/$defs/text" )) schema schema_validate(schema, "ok", mode = "test") schema_ref("text")schema <- schema_doc(list( `$defs` = list(text = schema_check("string")), `$ref` = "#/$defs/text" )) schema schema_validate(schema, "ok", mode = "test") schema_ref("text")
Replace a schema node
schema_replace(x, path = "$", value)schema_replace(x, path = "$", value)
x |
A |
path |
Path to the target schema node. Use |
value |
Replacement schema fragment using the same list syntax accepted
by |
A modified SchemaDoc.
schema <- schema_doc(list( check = list(kind = "list"), fields = list(id = schema_check("int")) )) schema <- schema_replace(schema, "$id", schema_check("int", lower = 1)) schema schema_validate(schema, list(id = 1L), mode = "test")schema <- schema_doc(list( check = list(kind = "list"), fields = list(id = schema_check("int")) )) schema <- schema_replace(schema, "$id", schema_check("int", lower = 1)) schema schema_validate(schema, list(id = 1L), mode = "test")
Set or remove a schema node description
schema_set_desc(x, path = "$", description = NULL)schema_set_desc(x, path = "$", description = NULL)
x |
A |
path |
Path to the target schema node. Use |
description |
Optional description string. Use |
A modified SchemaDoc.
schema <- schema_doc(schema_check("string")) schema_set_desc(schema, "$", "A non-empty label.")schema <- schema_doc(schema_check("string")) schema_set_desc(schema, "$", "A non-empty label.")
Set a schema node keys rule
schema_set_keys(x, path = "$", ...)schema_set_keys(x, path = "$", ...)
x |
A |
path |
Path to the target schema node. Use |
... |
Named |
A modified SchemaDoc.
schema <- schema_doc(list(check = list(kind = "list"))) schema schema_validate(schema, list(id = 1L), mode = "test") schema <- schema_set_keys(schema, type = "named", must.include = "id") schema schema_validate(schema, list(id = 1L), mode = "assert")schema <- schema_doc(list(check = list(kind = "list"))) schema schema_validate(schema, list(id = 1L), mode = "test") schema <- schema_set_keys(schema, type = "named", must.include = "id") schema schema_validate(schema, list(id = 1L), mode = "assert")
Set or replace a container rest schema
schema_set_rest(x, field, path = "$")schema_set_rest(x, field, path = "$")
x |
A |
field |
Schema fragment using the same list syntax accepted by
|
path |
Path to the target container node. Use |
A modified SchemaDoc.
schema <- schema_doc(list( check = list(kind = "list"), keys = list(type = "unnamed") )) schema <- schema_set_rest(schema, schema_check("string")) schema schema_validate(schema, list("a", "b"), mode = "test")schema <- schema_doc(list( check = list(kind = "list"), keys = list(type = "unnamed") )) schema <- schema_set_rest(schema, schema_check("string")) schema schema_validate(schema, list("a", "b"), mode = "test")
schema_validate() validates an R object against a SchemaDoc,
SchemaFlat, or flattened schema node. When validating many inputs against
the same schema, flatten it once with schema_flatten() and reuse the
flattened schema.
schema_validate(schema, x, mode = "assert", name = NULL, ...)schema_validate(schema, x, mode = "assert", name = NULL, ...)
schema |
A |
x |
Input object to validate. |
mode |
One of |
name |
Optional display name used in validation messages. |
... |
Reserved for future extension. |
In "assert" mode, invisibly returns x or throws an error. In
"check" mode, returns TRUE or a diagnostic string. In "test" mode,
returns TRUE or FALSE. In "expect" mode, returns a testthat-style
expectation object.
schema <- schema_doc(list( check = list(kind = "list"), fields = list(id = list(check = list(kind = "int", lower = 1))) )) schema schema_validate(schema, list(id = 1L), mode = "test") schema_validate(schema, list(id = 0L), mode = "check", name = "payload") flat <- schema_flatten(schema) schema_validate(flat, list(id = 2L), mode = "test")schema <- schema_doc(list( check = list(kind = "list"), fields = list(id = list(check = list(kind = "int", lower = 1))) )) schema schema_validate(schema, list(id = 1L), mode = "test") schema_validate(schema, list(id = 0L), mode = "check", name = "payload") flat <- schema_flatten(schema) schema_validate(flat, list(id = 2L), mode = "test")
schema_where_path() matches logical schema paths. schema_where_check()
matches check nodes by kind.
schema_where_path(pattern, fixed = FALSE) schema_where_check(kind = NULL)schema_where_path(pattern, fixed = FALSE) schema_where_check(kind = NULL)
pattern |
Pattern passed to |
fixed |
Whether |
kind |
Optional check kind to match, such as |
schema_where_check() matches check nodes present in the schema tree being
walked. It does not resolve $ref targets while querying an authoring
SchemaDoc; use schema_flatten() first if a query should see referenced
definitions through the flattened schema.
A predicate function with signature function(path, node).
by_path <- schema_where_path("(^|\\$)`date-parts`\\$rest$") by_int <- schema_where_check("int") schema <- schema_infer(list(id = 1L)) schema schema_find(schema, by_int)by_path <- schema_where_path("(^|\\$)`date-parts`\\$rest$") by_int <- schema_where_check("int") schema <- schema_infer(list(id = 1L)) schema schema_find(schema, by_int)
schema_read() reads schema JSON into a SchemaDoc. schema_write()
serializes schema objects to schema JSON. Both functions require the
suggested package jsonlite.
schema_write(x, path, overwrite = FALSE, pretty = TRUE, auto_unbox = TRUE) schema_read(txt)schema_write(x, path, overwrite = FALSE, pretty = TRUE, auto_unbox = TRUE) schema_read(txt)
x |
A schema object accepted by |
path |
Output file path. |
overwrite |
Whether an existing output file may be overwritten. |
pretty |
Whether JSON output should be pretty-printed. |
auto_unbox |
Passed to |
txt |
JSON text, local file path, or URL accepted by
|
schema_read() returns a SchemaDoc. schema_write() invisibly
returns path.
schema <- schema_infer(list(id = 1L)) schema path <- tempfile(fileext = ".json") schema_write(schema, path) schema_read(path)schema <- schema_infer(list(id = 1L)) schema path <- tempfile(fileext = ".json") schema_write(schema, path) schema_read(path)