OffsetMap carries LeafMeta; read/write_field dispatch on it (ADR-012 §2b, plan phase 5)

Prerequisite (review #005 M2): Hash added to Endian/VariableEncoding
derives (additive; fieldless Eq enums), and to ByteRange.

- New public types LeafMeta { kind, encoding, endian } (Copy + Eq +
  Hash) and OffsetEntry { range, meta } (start()/end() accessors),
  re-exported from lib.rs. Deferred decision 2 resolved: struct —
  get(path) -> Option<&OffsetEntry>, iter() -> (&str, &OffsetEntry).
  Storage: Vec<(String, OffsetEntry)>.
- LeafMeta computed at compute time with effective endian threaded
  through the aligned walk (container default -> field override,
  propagated into nested-struct probes and array elements via the
  referring field, matching the aligned materializer).
- engine read_field/write_field dispatch on the entry's LeafMeta:
  the per-access BastDoc re-parse + lookup_leaf_field walk +
  LeafFieldInfo are gone — the last two review #004 M1 sites.
- Parity note: lookup_leaf_field computed nested-struct defaults from
  the nested struct's own endian annotation; the map now agrees with
  the aligned materializer and packed ReadPlan (referring-field
  propagation). The old divergence (nested struct declaring endian
  under a field that also declares one) is closed; no test pinned it.
- Behavior change: read_field on a map-absent path (whole-struct
  field) errors Offset ("field not found") instead of Access
  ("composite types"); the composite-path test accepted either.
- materialize_aligned's four offset_map.get call sites updated to
  .range.start. alktty/alkcall untouched (bench never uses
  OffsetMap::get; alkcall has no dependency yet).

Verification: 465 tests pass (offset_map tests updated to the
OffsetEntry shape with per-kind LeafMeta expectations; engine test
for the old lookup walk rewritten to assert map entries carry the
LeafMeta); clippy -D warnings clean; cargo doc zero warnings; wasm32
release build green.
This commit is contained in:
glm-5.3-flash committed 2026-09-02 09:13:48 +00:00
1 parent b7c7dbe2a1
commit 255c8c493e
7 files changed
+248 -188

No files matched your search

+34 -34
View File
@@ -44,29 +44,29 @@ fn fixed_size_round_trip_via_offset_map() -> Result<(), AlkTypeError> {
let mut buffer = vec![0u8; offset_map.total_size()];
let id_range = offset_map.get("id").expect("id range");
data_access::write_u32(&mut buffer, id_range.start, 42, "id", Endian::Little)?;
data_access::write_u32(&mut buffer, id_range.start(), 42, "id", Endian::Little)?;
let score_range = offset_map.get("score").expect("score range");
data_access::write_f32(&mut buffer, score_range.start, 1.5, "score", Endian::Little)?;
data_access::write_f32(&mut buffer, score_range.start(), 1.5, "score", Endian::Little)?;
let flag_range = offset_map.get("flag").expect("flag range");
data_access::write_u8(&mut buffer, flag_range.start, 1, "flag")?;
data_access::write_u8(&mut buffer, flag_range.start(), 1, "flag")?;
let count_range = offset_map.get("count").expect("count range");
data_access::write_u16(
&mut buffer,
count_range.start,
count_range.start(),
1000,
"count",
Endian::Little,
)?;
assert_eq!(
data_access::read_u32(&buffer, id_range.start, "id", Endian::Little)?,
data_access::read_u32(&buffer, id_range.start(), "id", Endian::Little)?,
42
);
let score = data_access::read_f32(&buffer, score_range.start, "score", Endian::Little)?;
let score = data_access::read_f32(&buffer, score_range.start(), "score", Endian::Little)?;
assert!((score - 1.5).abs() < 0.001, "score: {score}");
assert_eq!(data_access::read_u8(&buffer, flag_range.start, "flag")?, 1);
assert_eq!(data_access::read_u8(&buffer, flag_range.start(), "flag")?, 1);
assert_eq!(
data_access::read_u16(&buffer, count_range.start, "count", Endian::Little)?,
data_access::read_u16(&buffer, count_range.start(), "count", Endian::Little)?,
1000
);
Ok(())
@@ -184,29 +184,29 @@ fn nested_struct_round_trip_via_offset_map() -> Result<(), AlkTypeError> {
let header_magic = offset_map.get("header.magic").expect("header.magic");
let payload_prefix = offset_map.get("payload").expect("payload");
assert_eq!(header_version.start, 0);
assert_eq!(header_magic.start, 4);
assert_eq!(payload_prefix.start, 8);
assert_eq!(header_version.start(), 0);
assert_eq!(header_magic.start(), 4);
assert_eq!(payload_prefix.start(), 8);
let data = b"body-data".to_vec();
let mut buffer = vec![0u8; offset_map.total_size() + data.len()];
data_access::write_u32(
&mut buffer,
header_version.start,
header_version.start(),
1,
"header.version",
Endian::Little,
)?;
data_access::write_u32(
&mut buffer,
header_magic.start,
header_magic.start(),
0xCAFEBABE,
"header.magic",
Endian::Little,
)?;
data_access::write_bytes(
&mut buffer,
payload_prefix.start,
payload_prefix.start(),
&data,
"payload",
Endian::Little,
@@ -215,18 +215,18 @@ fn nested_struct_round_trip_via_offset_map() -> Result<(), AlkTypeError> {
assert_eq!(
data_access::read_u32(
&buffer,
header_version.start,
header_version.start(),
"header.version",
Endian::Little
)?,
1
);
assert_eq!(
data_access::read_u32(&buffer, header_magic.start, "header.magic", Endian::Little)?,
data_access::read_u32(&buffer, header_magic.start(), "header.magic", Endian::Little)?,
0xCAFEBABE
);
assert_eq!(
data_access::read_bytes(&buffer, payload_prefix.start, "payload", Endian::Little)?,
data_access::read_bytes(&buffer, payload_prefix.start(), "payload", Endian::Little)?,
&data[..]
);
Ok(())
@@ -257,9 +257,9 @@ fn nested_struct_round_trip_via_engine_aligned() -> Result<(), AlkTypeError> {
let engine = AlkTypeEngine::compile(&doc, "S", LayoutMode::Aligned, None)?;
let offset_map = engine.offset_map().expect("aligned mode");
assert_eq!(offset_map.get("header.version").unwrap().start, 0);
assert_eq!(offset_map.get("header.flags").unwrap().start, 1);
assert_eq!(offset_map.get("payload_len").unwrap().start, 4);
assert_eq!(offset_map.get("header.version").unwrap().start(), 0);
assert_eq!(offset_map.get("header.flags").unwrap().start(), 1);
assert_eq!(offset_map.get("payload_len").unwrap().start(), 4);
let mut buffer = vec![0u8; offset_map.total_size()];
engine.write_field(&mut buffer, "header.version", &FieldValue::U8(1))?;
@@ -302,23 +302,23 @@ fn big_endian_round_trip_via_offset_map() -> Result<(), AlkTypeError> {
let id_range = offset_map.get("id").expect("id");
let offset_range = offset_map.get("offset").expect("offset");
assert_eq!(id_range.start, 0);
assert_eq!(offset_range.start, 8);
assert_eq!(id_range.start(), 0);
assert_eq!(offset_range.start(), 8);
let value: f64 = std::f64::consts::PI;
let mut buffer = vec![0u8; offset_map.total_size()];
data_access::write_u32(&mut buffer, id_range.start, 0x01020304, "id", endian)?;
data_access::write_f64(&mut buffer, offset_range.start, value, "offset", endian)?;
data_access::write_u32(&mut buffer, id_range.start(), 0x01020304, "id", endian)?;
data_access::write_f64(&mut buffer, offset_range.start(), value, "offset", endian)?;
assert_eq!(&buffer[0..4], &[0x01, 0x02, 0x03, 0x04]);
assert_eq!(&buffer[4..8], &[0x00, 0x00, 0x00, 0x00]);
assert_eq!(&buffer[8..16], value.to_be_bytes());
assert_eq!(
data_access::read_u32(&buffer, id_range.start, "id", endian)?,
data_access::read_u32(&buffer, id_range.start(), "id", endian)?,
0x01020304
);
let read = data_access::read_f64(&buffer, offset_range.start, "offset", endian)?;
let read = data_access::read_f64(&buffer, offset_range.start(), "offset", endian)?;
assert!((read - value).abs() < 1e-12);
Ok(())
}
@@ -342,17 +342,17 @@ fn alignment_padding_round_trip_u8_then_u32() -> Result<(), AlkTypeError> {
let flag_range = offset_map.get("flag").expect("flag");
let id_range = offset_map.get("id").expect("id");
assert_eq!(flag_range.start, 0);
assert_eq!(flag_range.end, 1);
assert_eq!(id_range.start, 4);
assert_eq!(id_range.end, 8);
assert_eq!(flag_range.start(), 0);
assert_eq!(flag_range.end(), 1);
assert_eq!(id_range.start(), 4);
assert_eq!(id_range.end(), 8);
assert_eq!(offset_map.total_size(), 8);
let mut buffer = vec![0u8; offset_map.total_size()];
data_access::write_u8(&mut buffer, flag_range.start, 0xAB, "flag")?;
data_access::write_u8(&mut buffer, flag_range.start(), 0xAB, "flag")?;
data_access::write_u32(
&mut buffer,
id_range.start,
id_range.start(),
0x01020304,
"id",
Endian::Little,
@@ -363,11 +363,11 @@ fn alignment_padding_round_trip_u8_then_u32() -> Result<(), AlkTypeError> {
assert_eq!(&buffer[4..8], 0x01020304u32.to_le_bytes());
assert_eq!(
data_access::read_u8(&buffer, flag_range.start, "flag")?,
data_access::read_u8(&buffer, flag_range.start(), "flag")?,
0xAB
);
assert_eq!(
data_access::read_u32(&buffer, id_range.start, "id", Endian::Little)?,
data_access::read_u32(&buffer, id_range.start(), "id", Endian::Little)?,
0x01020304
);
Ok(())