Reader
in package
Which schema a decoded struct is read with, given the version it was written with and the versions loaded (DXNS.md §8). Shared by the text parser and the binary decoder, so both answer every case the same way -- mirrors `Dextrin.Schema.Reader`:
- No version, or the latest loaded: read with the latest, exactly.
- Newer than anything loaded: read against the latest. Text matches fields by name; binary assumes positions are unchanged, drops the items beyond the reader's own and leaves missing optional fields absent. A newer version that reordered or removed fields is misread, without an error whenever the types agree -- the documented risk of reading forward.
- Older and loaded: read with that version's own schema and handed
to the materializer, which upgrades it. Without one it is refused,
schema/no-materializer: reading old data as if it were the latest would be a guess. - Older and not loaded: refused,
schema/unknown-version, even with a materializer, which would receive no field names.
What is built from the fields: the schema's materializer, when one
is registered, is called for every struct of its schema, whatever the
version, as $materializer($name, $version, $fields) -- $version
being the one the fields were read with, $fields an array keyed by
field name. Its result is checked against the latest schema; a throw,
or a result the latest schema rejects, is schema/materializer.
Without a materializer the latest version comes back as a
DXNStruct at that version, its fields in the schema's order.
Nested structs are built first.
Table of Contents
Methods
- read() : Registry}|null
- `$struct`, as decoded, read against `$registry`. Answers the value and the registry to carry on with, or `null` when the struct's name has no schema at all -- it stays opaque. Throws a categorised {@see DXNError}, or a {@see SchemaValidationError} the caller wraps as a schema violation.
- __construct() : mixed
- built() : mixed
- forward() : DXNStruct
- A newer writer's positional items, by the reader's own field order: positions are assumed unchanged, items beyond the reader's fields are dropped, and fields beyond the items are absent. A keyed struct already carries its names.
- materialized() : Registry}
- The fields read with `$reading`, then built into a value: by the materializer when there is one, checked against `$latest`; as a generic struct at `$latest`'s version when there is none. Wrapped in {@see Validated} so an outer schema's reference can tell where it came from.
- materializerError() : DXNError
-
separated()
: DXNStruct, 1: list
} - `$struct` with only the fields `$reading` declares, and its extra fields apart (DXNS.md §7): a keyed struct's undeclared names join the extras. A name given twice -- a declared field and an extra of the same name, or a keyed field written twice -- is refused: an extra never shadows a declared field. A positional struct gives every declared name, by position.
Methods
read()
`$struct`, as decoded, read against `$registry`. Answers the value and the registry to carry on with, or `null` when the struct's name has no schema at all -- it stays opaque. Throws a categorised {@see DXNError}, or a {@see SchemaValidationError} the caller wraps as a schema violation.
public
static read(Registry $registry, DXNStruct $struct) : Registry}|null
Parameters
Return values
Registry}|null__construct()
private
__construct() : mixed
built()
private
static built(Registry $registry, callable(string, int, array<int|string, mixed>): mixed $materializer, string $name, Compiled $reading, Compiled $latest, array<int, array{0: string, 1: mixed}> $pairs, array<int, array{0: mixed, 1: mixed}> $extra) : mixed
Parameters
forward()
A newer writer's positional items, by the reader's own field order: positions are assumed unchanged, items beyond the reader's fields are dropped, and fields beyond the items are absent. A keyed struct already carries its names.
private
static forward(Compiled $latest, DXNStruct $struct) : DXNStruct
Parameters
Return values
DXNStructmaterialized()
The fields read with `$reading`, then built into a value: by the materializer when there is one, checked against `$latest`; as a generic struct at `$latest`'s version when there is none. Wrapped in {@see Validated} so an outer schema's reference can tell where it came from.
private
static materialized(Registry $registry, Compiled $reading, Compiled $latest, DXNStruct $struct) : Registry}
Parameters
Return values
Registry}materializerError()
private
static materializerError(string $name, string $what) : DXNError
Parameters
- $name : string
- $what : string
Return values
DXNErrorseparated()
`$struct` with only the fields `$reading` declares, and its extra fields apart (DXNS.md §7): a keyed struct's undeclared names join the extras. A name given twice -- a declared field and an extra of the same name, or a keyed field written twice -- is refused: an extra never shadows a declared field. A positional struct gives every declared name, by position.
private
static separated(Compiled $reading, DXNStruct $struct) : DXNStruct, 1: list}