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:
glm-5.3-flash committed 2026-09-02 07:19:54 +00:00
1 parent e4636e6a44
commit ff85258d03
3 files changed
+1283 -10

No files matched your search

+8 -3
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff