php-dextrin

Validator
in package

FinalYes

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
$compiled : Compiled
$struct : DXNStruct
$registry : Registry
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
$compiled : Compiled
$value : mixed
$registry : Registry
Return values
Validated

validateTreeForEncode()

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

checkType()

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
$name : string
$value : mixed
$type : TypeExpr
$ctx : Context

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
$field : Field
$given : array<string, mixed>
$registry : Registry

resolveFields()

private static resolveFields(Compiled $compiled, array<string, mixed> $given, Registry $registry) : array<string, mixed>
Parameters
$compiled : Compiled
$given : array<string, mixed>
$registry : Registry
Return values
array<string, mixed>

schemaNameFor()

private static schemaNameFor(mixed $value, Registry $registry) : Compiled}|null
Parameters
$value : mixed
$registry : Registry
Return values
Compiled}|null

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
Return values
array<string, mixed>
On this page

Search results