Skip to content

Add source-side make plumbing hooks#58

Draft
quinnj wants to merge 3 commits into
mainfrom
claude/bare-styles-extract
Draft

Add source-side make plumbing hooks#58
quinnj wants to merge 3 commits into
mainfrom
claude/bare-styles-extract

Conversation

@quinnj

@quinnj quinnj commented Jun 12, 2026

Copy link
Copy Markdown
Member

Summary

  • Add StructUtils.extract as the source-side leaf conversion boundary used by make.
  • Add StructUtils.preparekey so source packages can normalize internal key representations before liftkey.
  • Add StructUtils.handleunknownfield so source packages can enforce source-local unknown-field policy without overloading the user-facing unknownfield hook.
  • Bump StructUtils to 2.9.0 for the new hooks.

Why

This gives format/source packages a clean place to handle source-owned representations and traversal state while keeping user extension hooks focused on style and target type dispatch. The handleunknownfield hook specifically avoids opposite-axis ambiguities between source-specific unknown-field policy and user-defined unknownfield(::MyStyle, ::Type{T}, ...) methods.

Validation

  • julia --startup-file=no --project=. -e 'using Pkg; Pkg.test()'
  • JSON integration check in a temp environment with local StructUtils and JSON branches: Pkg.test("JSON")
  • Focused JSON unknown-field ambiguity repro now passes with zero unknownfield-related ambiguities
  • julia +1.9 --startup-file=no --project=. -e 'using StructUtils'
  • julia +1.10 --startup-file=no --project=. -e 'using StructUtils'

Co-authored by Codex

quinnj and others added 3 commits June 12, 2026 11:53
extract(style, T, source, tags) is the boundary between the make recursion
and leaf-value conversion. Format packages overload it for source types they
own; users keep overloading lift with (style, target-type) and may return
plain values (normalized here, absorbing JSON.jl's _liftresult).

preparekey lets source packages normalize internal key representations
(e.g. JSON.jl's PtrString) before liftkey sees them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Without this, deeply nested struct targets explode compile time: after
Julia's recursion limiter widens the target type mid-recursion, abstract
extract call sites match 2-3 methods and inference explores the large
lazy-driver body per context (JSON.jl's Store benchmark struct: 1065s).
With @max_methods 1, abstract sites bail to Any immediately while every
concrete site (the entire static hot path) still infers precisely —
making nested-struct compile times faster than the pre-extract design
(Store: 17s -> 2.4s).

Also add extract/preparekey unit tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add handleunknownfield as a source-side dispatch point that delegates to the existing user-facing unknownfield hook by default. This lets source packages enforce source-local unknown-field policy without defining opposite-axis methods on unknownfield itself.
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.

1 participant