Implement ReadPlan type + compile (ADR-011 step 1, plan phase 1)
Pure addition: the packed read-side compiled form (src/read_plan.rs) and lib.rs wiring (module + re-exports of ReadPlan, FieldPlan, CompositePlan, ReadKind, DiscriminatorPlan). No existing engine code touched — phases 2-5 wire the plan into the reader/materializer/engine. - Refined union shape (ADR-011 as refined by review #005): CompositePlan::Union { disc, shared, variants } with shared: Option<Box<ReadPlan>> for field-disc unions and variants: Vec<(String, CompositePlan)> — no VariantPlan/VariantKind, nested-union variants work by ordinary CompositePlan recursion (restores the 0.2.0 capability the POC rejected). - by_name is BTreeMap (ADR-012 §1 Hash-derive prerequisite). - True array strides (deferred decision 4): fixed struct/nested-array elements compute their real stride via fixed_composite_size; variable-length elements stay 0. 0.2.0 returned 0 for fixed struct arrays; that behavioral change rides the 0.3.0 bump (phase 2 will surface it through SequentialReader). - Endianness: effective endian baked at every node. Parity lock: the plan propagates the referring field's effective endian into nested structs/unions — what the 0.2.0 packed reader/materializer actually do — and ignores nested containers' own endian annotations (the POC baked s.endian() there; latent divergence, never exercised by its equivalence tests). Nested-annotation tests lock this in. - Untrusted input: compile carries its own depth cap (128) + definition-level cycle set (mirrors ValidationPlan::compile), so standalone compile is safe on adversarial docs: cyclic refs, deep chains, dangling refs, non-struct roots, and non-struct/union variants all surface as AlkTypeError::Schema, never a panic. Overflow-safe stride arithmetic (checked_mul). Verification: 388 tests pass (355 existing + 33 new: every BastType arm coverage, field-disc shared/nested-union compile shape, stride computation, endian parity, cycle/depth/malformed rejection, Send + Sync static-bound assertion); clippy -D warnings clean; cargo doc zero warnings; wasm32-unknown-unknown release build green. Next: phase 2 (SequentialReader + materialize_packed consume the plan).
This commit is contained in:
1 parent
e4636e6a44
commit
ff85258d03
3 files changed
+1283
-10
No files matched your search
@@ -1,7 +1,7 @@
|
||||
---
|
||||
status: in-progress
|
||||
created: 2026-08-19
|
||||
last_updated: 2026-08-31
|
||||
last_updated: 2026-09-02
|
||||
adr: ADR-011, ADR-012
|
||||
---
|
||||
|
||||
@@ -113,14 +113,26 @@ accessors (signatures), `FieldValue`, `AlkTypeKind`, `AlkTypeError`,
|
||||
bug, the stride is behaviorally observable, and we're bumping. The
|
||||
plan step calls this out explicitly. Decided in phase 2.
|
||||
|
||||
## Phase 1 — `ReadPlan` type + `compile` (ADR-011 step 1)
|
||||
## Phase 1 — `ReadPlan` type + `compile` (ADR-011 step 1) — **DONE (2026-09-02)**
|
||||
|
||||
> **Status: implemented.** `src/read_plan.rs` builds the refined
|
||||
> `CompositePlan::Union` shape (`shared: Option<Box<ReadPlan>>` +
|
||||
> `variants: Vec<(String, CompositePlan)>`, no `VariantPlan`/`VariantKind`)
|
||||
> with eager `$ref` resolution, `BTreeMap` `by_name`, field-disc `shared`
|
||||
> sub-plans, nested-union variant support, and true array strides
|
||||
> (deferred decision 4 resolved: fixed struct arrays compute their real
|
||||
> stride, not the 0.2.0 reader's `0`). Two parity notes recorded as
|
||||
> compile-behavior locks in tests: (a) the plan propagates the
|
||||
> *referring field's* effective endianness into nested structs/unions —
|
||||
> exactly what the 0.2.0 packed reader/materializer do — rather than
|
||||
> consulting nested containers' own `endian` annotations (the POC baked
|
||||
> `s.endian()` there; its equivalence tests never covered a nested
|
||||
> annotation, so the divergence was latent); (b) `compile` carries its
|
||||
> own depth cap (128) + definition-level cycle set, so standalone
|
||||
> `ReadPlan::compile` is untrusted-input-safe independent of the
|
||||
> meta-schema and the engine's `ValidationPlan` gate.
|
||||
|
||||
**Goal:** Add the `ReadPlan`/`FieldPlan`/`CompositePlan`/`ReadKind`/
|
||||
`DiscriminatorPlan` types and `ReadPlan::compile(&Value, &str) ->
|
||||
Result<Self, AlkTypeError>`. Pure addition; no existing code touched.
|
||||
This is the foundation — later phases wire it into the engine and
|
||||
reader. (The POC's `VariantPlan`/`VariantKind` types are **dropped**
|
||||
in the production shape — see the union-shape note below.)
|
||||
|
||||
**ADR reference:** [ADR-011 §The `ReadPlan` shape](../architecture/decisions/011-compiled-read-plan-for-packed-mode.md#the-readplan-shape),
|
||||
[ADR-011 §Construction](../architecture/decisions/011-compiled-read-plan-for-packed-mode.md#construction).
|
||||
|
||||
+8
-3
@@ -12,9 +12,10 @@
|
||||
//! Borrows from the source `serde_json::Value` without cloning field
|
||||
//! data.
|
||||
//! - **Layout engine** ([`offset_map`], [`layout_builder`],
|
||||
//! [`sequential_reader`]): Two layout modes — aligned static for
|
||||
//! mmap-friendly formats, packed sequential for protocol wire formats.
|
||||
//! All three consume the BAST typed tree.
|
||||
//! [`sequential_reader`], [`read_plan`]): Two layout modes — aligned
|
||||
//! static for mmap-friendly formats, packed sequential for protocol
|
||||
//! wire formats. All consume the BAST typed tree; `read_plan` is the
|
||||
//! packed read-side compiled form (ADR-011).
|
||||
//! - **Data access** ([`data_access`]): Typed read/write at computed
|
||||
//! offsets, zero-copy for fixed-size types.
|
||||
//! - **TUnion dispatch** ([`tunion`]): Byte-offset and field-name
|
||||
@@ -52,6 +53,7 @@ pub mod error;
|
||||
pub mod layout_builder;
|
||||
pub mod materialize;
|
||||
pub mod offset_map;
|
||||
pub mod read_plan;
|
||||
pub mod schema;
|
||||
pub mod sequential_reader;
|
||||
pub mod tunion;
|
||||
@@ -68,6 +70,9 @@ pub use engine::{LayoutMode, AlkTypeEngine};
|
||||
pub use error::AlkTypeError;
|
||||
pub use layout_builder::{FieldPosition, LayoutBuilder, PackedLayout};
|
||||
pub use offset_map::{ByteRange, OffsetMap};
|
||||
pub use read_plan::{
|
||||
CompositePlan, DiscriminatorPlan, FieldPlan, ReadKind, ReadPlan,
|
||||
};
|
||||
pub use schema::{Endian, AlkTypeKind, VariableEncoding};
|
||||
pub use sequential_reader::{FieldValue, SequentialReader};
|
||||
pub use tunion::UnionDispatch;
|
||||
|
||||
+1256
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user