Skip to content

pxf: Result::Directives() / Result::Tables() accessors#12

Merged
trendvidia merged 1 commit into
mainfrom
result-directive-accessors
May 12, 2026
Merged

pxf: Result::Directives() / Result::Tables() accessors#12
trendvidia merged 1 commit into
mainfrom
result-directive-accessors

Conversation

@trendvidia
Copy link
Copy Markdown
Owner

Summary

Third PR in the v0.72–v0.75 cpp catch-up. The fast-path decoder previously walked directives just enough to satisfy the standalone constraint and arity checks; it discarded their content. This PR wires the parsed shape onto `Result` so consumers can read the document-root directive list after `UnmarshalFull` returns.

API additions on `Result`:

  • `Directives()` → `const vector&` — generic `@ *(prefix) [{ ... }]` blocks in source order. `body` holds the raw bytes between `{` and `}`, preserved verbatim for downstream re-parsing (chameleon's `@header` reader, etc.). Single-prefix populates the back-compat `type` field per v0.72.0 shape.
  • `Tables()` → `const vector&` — `@table` directives with full column metadata and parsed cell `ValuePtr` per row, faithful to the three-state cell grammar (absent / present-but-null / present-with-value).

Fast path (`decode_fast.cc`):

  • `ConsumeDirectives` now builds `Directive` / `TableDirective` structs inline, conditionally appending to `result_` when non-null
  • `Unmarshal` (`Result=nullptr`) retains its zero-allocation contract: the fast path still walks and validates directives but allocates nothing on the prelude
  • New `ParseScalarCellValue` helper mirrors the scalar branches of the AST parser's `ParseValue`. Used by `@table` row parsing; list / block cell tokens are already rejected before it's called
  • Body bytes for `@` blocks are sliced via `lex_.Input().substr(open + 1, close - (open + 1))` using the `Position::offset` added in PR pxf: parser-side @<name>/@entry/@table directive grammar #9

Test plan

  • 14 new tests in `pxf_result_directives_test.cc` covering bare/single/multi-prefix directives, nested block body preservation, source-order multi-directive, `@type` not leaking into `Directives()`, `@table` columns / rows / concrete cell values, three-state cells, multi-table, directive+table coexistence, and the `Unmarshal` (no Result) regression check
  • All 198 tests pass locally (184 on main → +14 new)
  • CI green (clang-format, all matrix jobs, CodeQL)

Third PR of the v0.72-v0.75 cpp catch-up. The fast-path direct
decoder previously walked directives just enough to satisfy the
standalone constraint and arity checks; it discarded their content.
This PR wires the parsed shape onto Result so consumers can read the
document-root directive list after UnmarshalFull returns.

API additions on Result:
  - Directives() → const vector<Directive>& : generic
    `@<name> *(prefix) [{ ... }]` blocks in source order. body holds
    raw bytes between '{' and '}', preserved verbatim for downstream
    re-parsing (chameleon's @Header reader, etc.). Single-prefix
    populates the back-compat `type` field per v0.72.0 shape.
  - Tables() → const vector<TableDirective>& : @table directives
    with full column metadata and parsed cell ValuePtr per row,
    faithful to the three-state cell grammar (absent / present-null /
    present-with-value).
  - AddDirective(...) / AddTable(...) : internal mutators used by
    the fast path; not part of the consumer API.

Fast path (decode_fast.cc):
  - ConsumeDirectives builds Directive / TableDirective structs
    inline, conditionally appending to result_ when non-null.
    Unmarshal (Result=nullptr) retains its zero-allocation contract:
    the fast path still walks and validates directives but allocates
    nothing on the prelude.
  - New ParseScalarCellValue helper mirrors the scalar branches of
    the AST parser's ParseValue. Used by @table row parsing; list /
    block cell tokens are already rejected before it's called.
  - Body bytes for @<directive> blocks are sliced from
    lex_.Input().substr(open + 1, close - (open + 1)) using the
    Position::offset added in PR #9.

Tests (14 new in pxf_result_directives_test.cc, 198 total):
  - Empty document, bare / single-prefix / multi-prefix directives
  - @type does not leak into Directives()
  - Nested block body preserved verbatim
  - Multiple directives in source order
  - @table columns / rows / cells (concrete value tagging)
  - Three-state cells (absent / null / value)
  - Multiple tables in order
  - Directives + tables coexisting
  - Unmarshal (no Result) still succeeds (regression check on the
    result_-null branch)
@codecov-commenter
Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 51.93798% with 62 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/pxf/decode_fast.cc 50.40% 50 Missing and 12 partials ⚠️

📢 Thoughts on this report? Let us know!

@trendvidia trendvidia merged commit bd4685b into main May 12, 2026
10 checks passed
@trendvidia trendvidia deleted the result-directive-accessors branch May 12, 2026 09:58
@trendvidia trendvidia mentioned this pull request May 12, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants