// Code generated by cmd/genapi. DO NOT EDIT.

//go:build !ignore_autogenerated

// Package api contains the Telegram Bot API object types and method
// wrappers, generated from the live documentation by cmd/genapi.
package api

import (
	"github.com/goccy/go-json"
	"fmt"
	"io"
)

var _ = io.Discard   // keep import even if no fields use io
var _ = json.Marshal // keep import for UnmarshalXxx helpers
var _ = fmt.Errorf   // keep import for UnmarshalXxx helpers

{{range .Types}}
{{- $td := . -}}
{{if .OneOf}}
// {{.Name}} is a union type. The following concrete variants implement
// it:
{{range .OneOf}}//   - {{.}}
{{end}}//
{{docComment .Doc -}}
type {{.Name}} interface{ is{{.Name}}() }

{{range .OneOf}}
// is{{$td.Name}} is the marker method that makes {{.}} implement {{$td.Name}}.
func (*{{.}}) is{{$td.Name}}() {}
{{end}}
{{if hasDiscriminator .Name}}
// Unmarshal{{.Name}} decodes a {{.Name}} from JSON by inspecting the
// "{{discriminatorField .Name}}" field and dispatching to the correct concrete type.
func Unmarshal{{.Name}}(data []byte) ({{.Name}}, error) {
	var probe struct {
		V string `json:"{{discriminatorField .Name}}"`
	}
	if err := json.Unmarshal(data, &probe); err != nil {
		return nil, err
	}
	var v {{.Name}}
	switch probe.V {
{{range $val, $typ := discriminatorMap .Name}}	case {{printf "%q" $val}}:
		v = &{{$typ}}{}
{{end}}	default:
		return nil, fmt.Errorf("{{.Name}}: unknown {{discriminatorField .Name}} %q", probe.V)
	}
	if err := json.Unmarshal(data, v); err != nil {
		return nil, err
	}
	return v, nil
}
{{end}}
{{if isMaybeInaccessibleMessage .Name}}
// UnmarshalMaybeInaccessibleMessage decodes a JSON object into the correct
// MaybeInaccessibleMessage variant. Telegram uses the date field as a
// discriminator: date == 0 indicates InaccessibleMessage; any other value
// indicates a real Message.
func UnmarshalMaybeInaccessibleMessage(data []byte) (MaybeInaccessibleMessage, error) {
	var probe struct {
		Date int64 `json:"date"`
	}
	if err := json.Unmarshal(data, &probe); err != nil {
		return nil, fmt.Errorf("MaybeInaccessibleMessage: %w", err)
	}
	if probe.Date == 0 {
		v := &InaccessibleMessage{}
		if err := json.Unmarshal(data, v); err != nil {
			return nil, fmt.Errorf("InaccessibleMessage: %w", err)
		}
		return v, nil
	}
	v := &Message{}
	if err := json.Unmarshal(data, v); err != nil {
		return nil, fmt.Errorf("Message: %w", err)
	}
	return v, nil
}
{{end}}
{{else}}
{{docComment .Doc -}}
type {{.Name}} struct {
{{range .Fields}}{{docComment .Doc}}{{goField $td.Name .}}
{{end}}}
{{if variantHasDisc .Name}}
// MarshalJSON encodes {{.Name}} with the discriminator field
// "{{variantDiscField .Name}}" forced to {{printf "%q" (variantDiscValue .Name)}}.
// The hardcoded value frees callers from setting {{variantDiscGoField .Name}} by hand —
// any user-supplied value on the struct literal is overridden so a typo
// can't slip through to Telegram.
func (v *{{.Name}}) MarshalJSON() ([]byte, error) {
	type alias {{.Name}}
	return json.Marshal(&struct {
		{{variantDiscGoField .Name}} string `json:"{{variantDiscField .Name}}"`
		*alias
	}{
		{{variantDiscGoField .Name}}: {{printf "%q" (variantDiscValue .Name)}},
		alias: (*alias)(v),
	})
}
{{end}}
{{$unionFields := unionFields .}}{{if $unionFields}}
// UnmarshalJSON decodes {{.Name}} by dispatching union-typed fields
// ({{range $i, $u := $unionFields}}{{if $i}}, {{end}}{{$u.Field.Name}}{{end}}) through their concrete UnmarshalXxx helpers.
func (m *{{.Name}}) UnmarshalJSON(data []byte) error {
	type Alias {{.Name}}
	aux := &struct {
		{{range $unionFields}}{{.Field.Name}} json.RawMessage `json:"{{.Field.JSONName}},omitempty"`
		{{end}}*Alias
	}{Alias: (*Alias)(m)}
	if err := json.Unmarshal(data, aux); err != nil {
		return err
	}
	{{range $unionFields}}{{$f := .Field}}{{$u := .UnionName}}
	if len(aux.{{$f.Name}}) > 0 && string(aux.{{$f.Name}}) != "null" {
		{{if isArrayUnion $f.Type}}var raws []json.RawMessage
		if err := json.Unmarshal(aux.{{$f.Name}}, &raws); err != nil {
			return fmt.Errorf("decoding {{$f.JSONName}}: %w", err)
		}
		decoded := make([]{{$u}}, 0, len(raws))
		for i, r := range raws {
			v, err := Unmarshal{{$u}}(r)
			if err != nil {
				return fmt.Errorf("decoding {{$f.JSONName}}[%d]: %w", i, err)
			}
			decoded = append(decoded, v)
		}
		m.{{$f.Name}} = decoded
		{{else}}v, err := Unmarshal{{$u}}(aux.{{$f.Name}})
		if err != nil {
			return fmt.Errorf("decoding {{$f.JSONName}}: %w", err)
		}
		m.{{$f.Name}} = v
		{{end}}
	}
	{{end}}
	return nil
}
{{end}}
{{end}}
{{end}}
