feat(analyzer): a union parameter names a type instead of resting at any - #88
Merged
Conversation
A parameter with a genuine choice of types resolved to any: assignable, since everything is, but nothing in the package said what was valid. Typing it needed the encoders to stop writing the wrapper. Every generated union now answers unionValue, and derefParam unwraps through it, so the value the union carries goes on the wire under the parameter's own style: a scalar as itself, a list still exploded, and a union carrying nothing sends no parameter at all. The marker is an unexported method rather than a struct shape sniff, which a schema declaring a property named value would trip. With that in place the analyzer passes the name hint it had been withholding for exactly this reason, so union and inline-object parameters are typed and constructible.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #87.
Assignable, since everything satisfies
any, but nothing in the generated package said what was valid. This is the tail of #16.Why it was blocked, and what unblocked it
#82 deliberately withheld the name hint here. Synthesizing the type is easy; the problem is that a union is a struct, and the query encoder writes a struct as an object, so
either=42would have gone out as the wrapper's shape. Typing the field would have made the wire wrong.Every generated union now answers an unexported marker:
and
derefParam, which every parameter encoder already goes through, unwraps it:One place, so query, header, path, and cookie parameters all benefit. An unexported method rather than sniffing for a struct with a field named
Value, which a schema could legitimately declare.With the wire correct, the analyzer passes the hint:
Behavior worth knowing
deepObjectobject parameter still explodes.GetItem(ctx, id ListItemsEither). Existing behavior for inline unions, now visible in a signature.anyOf: [string, null]still collapses to*string.Tests
internal/analyzer/operations_test.go: a union parameter names a union type, two parameters of one shape share it, a nullable union still collapses tostring, and an inline object parameter is named.internal/generator/e2e_union_param_test.go: compiles and runs againsthttptest, checking an integer variant arrives as42and a string variant asabc, a list variant still explodes, header and path parameters unwrap too, an empty union sends nothing, adeepObjectinline object explodes intoat[lat]andat[lon], and a plain parameter is unaffected.One existing expectation changed:
TestNullableUnion_QueryParamsResolveToTheVariantTypeasserted that a real choice staysany, which was the behavior this replaces.gofmt,go vet ./..., andgo test ./...pass.