Validator
in package
Checks a value's fields against a {@see Compiled} schema (required fields and their types) -- shared by decode ({@see self::materialize()}, which also produces a materialized result) and encode-time validation ({@see self::validateForEncode()}/{@see self::validateTreeForEncode()}). Both directions reuse the exact same `resolveFields()`/`TypeExpr::matches()` field-checking; encode's own values are wrapped in the same {@see Validated} marker decode already uses, via `wrapAndCheck()`, so there's one type-checking implementation, not two that could drift.
Nothing is converted to make a value match (DXNS.md ยง7): a
schema accepts or rejects a value, and never changes what it means.
wrapAndCheck() rebuilds every container it walks from its children,
so a checked struct reaches the printer/binary encoder wrapped.
Enforcement is decode-time and fail-fast, with no lenient escape hatch to get the materialized value anyway -- a violation is always a thrown SchemaValidationError.
Table of Contents
Methods
- resolve() : array<int, array{0: string, 1: mixed}>
- `$struct`'s fields checked against `$compiled`: every declared field, in the schema's own order, as `[name, value]` pairs. A required field that is missing, or a value that does not match its declared type, is an error; an optional field that is missing takes its default, or stays absent when it has none -- DXN tells an absent field from one written `nil`. What is built from the result is {@see Reader}'s job.
- validateForEncode() : Validated
- Checks `$value` -- ordinary PHP data about to be encoded -- against `$compiled`. Returns the checked value, {@see Validated}-wrapped.
- validateTreeForEncode() : mixed
- Walks `$value` looking for every {@see DXNStruct} or registered application class instance anywhere in the tree and checks each one against its own schema, if the registry has one -- regardless of what any enclosing field's declared type is, recursing fully into whatever it finds. Returns the checked tree.
- __construct() : mixed
- checkCompiled() : Validated
- checkType() : mixed
- Conformed, not only matched: a shape in the field's type comes out with its defaults filled, and a `{:case}` reads its sibling from the struct's other fields (`$ctx`).
- rebuildChecked() : mixed
- Rebuilds `$value` in its *original* shape (a `DXNStruct`, or a real application class instance) with `$resolved`'s checked field values written back in. Without this, `checkCompiled()` would hand the printer/binary encoder a bare field map instead of something it actually knows how to encode (a plain array has no name of its own to recover `%Name{...}` wire syntax from) -- the encode-time analog of why `materialize()`'s decode-side default already produces a real, named result rather than discarding shape information.
- resolveField() : mixed
- The checked value of `$field`, or {@see Absent} for an optional field that was not given and has no default.
- resolveFields() : array<string, mixed>
- schemaNameFor() : Compiled}|null
- toNameMap() : array<string, mixed>
- toNameMapForEncode() : array<string, mixed>
- wrapAndCheck() : mixed
- `wrapAndCheck()` is the recursive core: for any value that's a named struct with a registered schema, check it (`checkCompiled()`) and wrap the result in `Validated`; otherwise recurse into whatever container it is, reconstructing it from the (possibly-wrapped) results so a wrapped grandchild survives all the way up to whichever ancestor's field type actually needs to see it.
- wrapChildren() : mixed
- wrapGiven() : array<string, mixed>
Methods
resolve()
`$struct`'s fields checked against `$compiled`: every declared field, in the schema's own order, as `[name, value]` pairs. A required field that is missing, or a value that does not match its declared type, is an error; an optional field that is missing takes its default, or stays absent when it has none -- DXN tells an absent field from one written `nil`. What is built from the result is {@see Reader}'s job.
public
static resolve(Compiled $compiled, DXNStruct $struct, Registry $registry) : array<int, array{0: string, 1: mixed}>
Parameters
Return values
array<int, array{0: string, 1: mixed}>validateForEncode()
Checks `$value` -- ordinary PHP data about to be encoded -- against `$compiled`. Returns the checked value, {@see Validated}-wrapped.
public
static validateForEncode(Compiled $compiled, mixed $value, Registry $registry) : Validated
Parameters
Return values
ValidatedvalidateTreeForEncode()
Walks `$value` looking for every {@see DXNStruct} or registered application class instance anywhere in the tree and checks each one against its own schema, if the registry has one -- regardless of what any enclosing field's declared type is, recursing fully into whatever it finds. Returns the checked tree.
public
static validateTreeForEncode(mixed $value, Registry $registry) : mixed
Parameters
- $value : mixed
- $registry : Registry
__construct()
private
__construct() : mixed
checkCompiled()
private
static checkCompiled(Compiled $compiled, mixed $value, Registry $registry) : Validated
Parameters
Return values
ValidatedcheckType()
Conformed, not only matched: a shape in the field's type comes out with its defaults filled, and a `{:case}` reads its sibling from the struct's other fields (`$ctx`).
private
static checkType(string $name, mixed $value, TypeExpr $type, Context $ctx) : mixed
Parameters
rebuildChecked()
Rebuilds `$value` in its *original* shape (a `DXNStruct`, or a real application class instance) with `$resolved`'s checked field values written back in. Without this, `checkCompiled()` would hand the printer/binary encoder a bare field map instead of something it actually knows how to encode (a plain array has no name of its own to recover `%Name{...}` wire syntax from) -- the encode-time analog of why `materialize()`'s decode-side default already produces a real, named result rather than discarding shape information.
private
static rebuildChecked(mixed $value, Compiled $compiled, array<string, mixed> $resolved) : mixed
A value that was neither of those (a bare PHP array, this port's
own map) is promoted to a keyed DXNStruct under
$compiled's own name: having just checked it against that
specific schema, the natural encoded form is %Name{...}, not a
bare, nameless %{...} map with no record that a check ever
happened.
PHP-specific limitation: rebuilding a real application class
instance writes checked field values back onto a clone via
direct property assignment, which throws if that property is
readonly (PHP has no generic "reconstruct with these fields
changed" for readonly properties the way JS's always-mutable
objects allow) -- a genuinely PHP-specific constraint the JS
port doesn't share, not something this port works around.
Parameters
- $value : mixed
- $compiled : Compiled
- $resolved : array<string, mixed>
resolveField()
The checked value of `$field`, or {@see Absent} for an optional field that was not given and has no default.
private
static resolveField(Field $field, array<string, mixed> $given, Registry $registry) : mixed
Parameters
resolveFields()
private
static resolveFields(Compiled $compiled, array<string, mixed> $given, Registry $registry) : array<string, mixed>
Parameters
Return values
array<string, mixed>schemaNameFor()
private
static schemaNameFor(mixed $value, Registry $registry) : Compiled}|null
Parameters
- $value : mixed
- $registry : Registry
Return values
Compiled}|nulltoNameMap()
private
static toNameMap(Compiled $compiled, DXNStruct $struct) : array<string, mixed>
Parameters
Return values
array<string, mixed>toNameMapForEncode()
private
static toNameMapForEncode(Compiled $compiled, mixed $value) : array<string, mixed>
Parameters
- $compiled : Compiled
- $value : mixed
Return values
array<string, mixed>wrapAndCheck()
`wrapAndCheck()` is the recursive core: for any value that's a named struct with a registered schema, check it (`checkCompiled()`) and wrap the result in `Validated`; otherwise recurse into whatever container it is, reconstructing it from the (possibly-wrapped) results so a wrapped grandchild survives all the way up to whichever ancestor's field type actually needs to see it.
private
static wrapAndCheck(mixed $value, Registry $registry) : mixed
Parameters
- $value : mixed
- $registry : Registry
wrapChildren()
private
static wrapChildren(mixed $value, Registry $registry) : mixed
Parameters
- $value : mixed
- $registry : Registry
wrapGiven()
private
static wrapGiven(array<string, mixed> $given, Registry $registry) : array<string, mixed>
Parameters
- $given : array<string, mixed>
- $registry : Registry