mirror of
https://github.com/lukaszraczylo/go-telegram.git
synced 2026-06-11 23:19:31 +00:00
fix(api): emit bare interface for all sealed-interface unions
Optional fields whose type was a sealed-interface union without an auto-decode discriminator (BotCommandScope, InputMedia, InputPaidMedia, InputProfilePhoto, InputStoryContent, InputMessageContent, InputPollMedia, InputPollOptionMedia, InlineQueryResult, PassportElementError) were emitted as *<Union> — pointer to interface, which is a Go anti-pattern: interfaces are already nil-able, and callers were forced to take addresses of concrete variants. The codegen path goType() guarded against pointer-wrapping using knownDiscriminators (only 13 unions with auto-decode dispatch), missing the 10 marker-only sealed interfaces. New package var knownInterfaceTypes is built from buildUnionTypeSet at emitter construction and covers both kinds. goType() now consults that. Net effect: - api/methods.gen.go: 3 *BotCommandScope and 2 *InputPollMedia fields become bare interface - api/types.gen.go: 14 *InputMessageContent and 1 *InputPollOptionMedia fields become bare interface Regression tests in api/unionparam_test.go cover both shapes: direct concrete-variant assignment, and nil omitempty on the bare interface field.
This commit is contained in:
+10
-1
@@ -168,9 +168,18 @@ type emitter struct {
|
||||
}
|
||||
|
||||
func newEmitter(api *spec.API, outDir string) *emitter {
|
||||
knownInterfaceTypes = buildUnionTypeSet(api)
|
||||
return &emitter{api: api, outDir: outDir, enums: planEnums(api)}
|
||||
}
|
||||
|
||||
// knownInterfaceTypes is the full set of sealed-interface union type names
|
||||
// (both auto-decoded ones in knownDiscriminators and marker-only ones from
|
||||
// types with OneOf). Populated at emitter construction. goType and
|
||||
// unionTypeFor consult this so optional fields of any union type stay
|
||||
// bare interface, never *Interface (which is meaningless in Go and trips
|
||||
// users at every call site).
|
||||
var knownInterfaceTypes = map[string]bool{}
|
||||
|
||||
// emitTypes renders types.gen.go.
|
||||
func (e *emitter) emitTypes() error {
|
||||
t, err := template.New("types").Funcs(funcs(e.enums)).Parse(typesTmpl)
|
||||
@@ -477,7 +486,7 @@ func goType(tr spec.TypeRef, optional bool) string {
|
||||
// multipart helpers (fileCheck, multipartFileEntry) call
|
||||
// f.IsLocalUpload() and dereference Reader, both of which
|
||||
// expect a pointer receiver.
|
||||
if _, isUnion := knownDiscriminators[tr.Name]; isUnion {
|
||||
if knownInterfaceTypes[tr.Name] {
|
||||
// Interface type — never add *.
|
||||
return tr.Name
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user