Skip to content

Improve and Fix Header Parsing#943

Open
wolveix wants to merge 16 commits into
mainfrom
fix-struct-header-parsing
Open

Improve and Fix Header Parsing#943
wolveix wants to merge 16 commits into
mainfrom
fix-struct-header-parsing

Conversation

@wolveix

@wolveix wolveix commented Jan 17, 2026

Copy link
Copy Markdown
Collaborator

#944 was merged as a successor to the original intention of this PR.


This PR enables recursion for findInType for findHeaders and findParams. I'm still exploring the implications of doing this, though my initial findings don't turn up anything negative. The main purpose of this is to allow named fields in input and output structs, which have been requested features for quite some time.

This PR:

We previously only iterated over struct fields if the struct belonged to a slice. We now iterate all struct fields regardless of whether it's a single object or part of a slice.
@codecov

codecov Bot commented Jan 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.88525% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.11%. Comparing base (fd8148e) to head (f7f7e18).

Files with missing lines Patch % Lines
huma.go 86.88% 5 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #943      +/-   ##
==========================================
- Coverage   93.16%   93.11%   -0.06%     
==========================================
  Files          23       23              
  Lines        4918     4968      +50     
==========================================
+ Hits         4582     4626      +44     
- Misses        272      275       +3     
- Partials       64       67       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wolveix wolveix marked this pull request as draft January 17, 2026 21:07
@wolveix

wolveix commented Feb 19, 2026

Copy link
Copy Markdown
Collaborator Author

@leonklingele if you get a chance, I'd love your thoughts on this :)

@leonklingele

Copy link
Copy Markdown
Contributor

@wolveix sorry for the very late reply. This lgtm! Let's get this merged?

@leonklingele

Copy link
Copy Markdown
Contributor

Hey @wolveix, I'm now in a situation where I'd benefit from this change 😄 Is there anything still missing here?

@wolveix

wolveix commented Jun 19, 2026

Copy link
Copy Markdown
Collaborator Author

I kinda wanted @danielgtaylor's feedback on it before merging 😅

wolveix added 4 commits June 19, 2026 15:17
findHeaders' depth check (len(i) > 1) dropped headers for fields promoted
via embedded structs that had no explicit header tag, a silent behavior
change from prior releases and inconsistent with Go field promotion (a
promoted field stopped behaving like a top-level field).

Replace the depth check with isPromotedField, which auto-names a header
from the field name only for surface-level fields: literal top-level
fields and fields reachable purely through embedded structs. Named nested
struct fields still require an explicit header tag (the new feature). Add
a regression test covering all three cases.
With params recursion enabled, a param declared on a pointer-nested input
struct (e.g. Filters *Filters with a query tag) was documented in the
OpenAPI spec but never populated at runtime: the intermediate pointer is
nil and the traversal skipped it, so the advertised param could never be
received.

Add findResult.EveryAlloc, which allocates nil pointers along the path so
nested fields can be set. A pointer it allocates is reset to nil when no
value below it was set, so an absent optional group stays nil instead of
becoming an empty struct. Use it for both the main and multipart input
param population paths. Add tests covering value- and pointer-nested
population and the absent-group-stays-nil case.
The public input path always populates a freshly-zeroed input, so slice and
map elements along a param path are empty and the slice/map branches in
everyAlloc never iterate at runtime, leaving them uncovered. Add a white-box
test that drives everyAlloc directly over populated slices/maps, an
allocated-and-kept pointer, an allocated-then-rolled-back pointer, a reused
pointer, and an unsupported kind.
@wolveix wolveix marked this pull request as ready for review June 20, 2026 23:34
@wolveix

wolveix commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator Author

@leonklingele I updated this PR, would appreciate your review :)

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.

Unable to create a wrapper func that also requires the *http.Request object Nested header on input

2 participants