// Code generated by gotdgen, DO NOT EDIT.

package tdapi

import (
	"context"
	"errors"
	"fmt"
	"sort"
	"strings"

	"go.uber.org/multierr"

	"go.mau.fi/mautrix-telegram/pkg/gotd/bin"
	"go.mau.fi/mautrix-telegram/pkg/gotd/tdjson"
	"go.mau.fi/mautrix-telegram/pkg/gotd/tdp"
	"go.mau.fi/mautrix-telegram/pkg/gotd/tgerr"
)

// No-op definition for keeping imports.
var (
	_ = bin.Buffer{}
	_ = context.Background()
	_ = fmt.Stringer(nil)
	_ = strings.Builder{}
	_ = errors.Is
	_ = multierr.AppendInto
	_ = sort.Ints
	_ = tdp.Format
	_ = tgerr.Error{}
	_ = tdjson.Encoder{}
)

// PaymentFormTypeRegular represents TL type `paymentFormTypeRegular#ba6d2f0f`.
type PaymentFormTypeRegular struct {
	// Full information about the invoice
	Invoice Invoice
	// User identifier of the payment provider bot
	PaymentProviderUserID int64
	// Information about the payment provider
	PaymentProvider PaymentProviderClass
	// The list of additional payment options
	AdditionalPaymentOptions []PaymentOption
	// Saved server-side order information; may be null
	SavedOrderInfo OrderInfo
	// The list of saved payment credentials
	SavedCredentials []SavedCredentials
	// True, if the user can choose to save credentials
	CanSaveCredentials bool
	// True, if the user will be able to save credentials, if sets up a 2-step verification
	// password
	NeedPassword bool
}

// PaymentFormTypeRegularTypeID is TL type id of PaymentFormTypeRegular.
const PaymentFormTypeRegularTypeID = 0xba6d2f0f

// construct implements constructor of PaymentFormTypeClass.
func (p PaymentFormTypeRegular) construct() PaymentFormTypeClass { return &p }

// Ensuring interfaces in compile-time for PaymentFormTypeRegular.
var (
	_ bin.Encoder     = &PaymentFormTypeRegular{}
	_ bin.Decoder     = &PaymentFormTypeRegular{}
	_ bin.BareEncoder = &PaymentFormTypeRegular{}
	_ bin.BareDecoder = &PaymentFormTypeRegular{}

	_ PaymentFormTypeClass = &PaymentFormTypeRegular{}
)

func (p *PaymentFormTypeRegular) Zero() bool {
	if p == nil {
		return true
	}
	if !(p.Invoice.Zero()) {
		return false
	}
	if !(p.PaymentProviderUserID == 0) {
		return false
	}
	if !(p.PaymentProvider == nil) {
		return false
	}
	if !(p.AdditionalPaymentOptions == nil) {
		return false
	}
	if !(p.SavedOrderInfo.Zero()) {
		return false
	}
	if !(p.SavedCredentials == nil) {
		return false
	}
	if !(p.CanSaveCredentials == false) {
		return false
	}
	if !(p.NeedPassword == false) {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (p *PaymentFormTypeRegular) String() string {
	if p == nil {
		return "PaymentFormTypeRegular(nil)"
	}
	type Alias PaymentFormTypeRegular
	return fmt.Sprintf("PaymentFormTypeRegular%+v", Alias(*p))
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*PaymentFormTypeRegular) TypeID() uint32 {
	return PaymentFormTypeRegularTypeID
}

// TypeName returns name of type in TL schema.
func (*PaymentFormTypeRegular) TypeName() string {
	return "paymentFormTypeRegular"
}

// TypeInfo returns info about TL type.
func (p *PaymentFormTypeRegular) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "paymentFormTypeRegular",
		ID:   PaymentFormTypeRegularTypeID,
	}
	if p == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Invoice",
			SchemaName: "invoice",
		},
		{
			Name:       "PaymentProviderUserID",
			SchemaName: "payment_provider_user_id",
		},
		{
			Name:       "PaymentProvider",
			SchemaName: "payment_provider",
		},
		{
			Name:       "AdditionalPaymentOptions",
			SchemaName: "additional_payment_options",
		},
		{
			Name:       "SavedOrderInfo",
			SchemaName: "saved_order_info",
		},
		{
			Name:       "SavedCredentials",
			SchemaName: "saved_credentials",
		},
		{
			Name:       "CanSaveCredentials",
			SchemaName: "can_save_credentials",
		},
		{
			Name:       "NeedPassword",
			SchemaName: "need_password",
		},
	}
	return typ
}

// Encode implements bin.Encoder.
func (p *PaymentFormTypeRegular) Encode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode paymentFormTypeRegular#ba6d2f0f as nil")
	}
	b.PutID(PaymentFormTypeRegularTypeID)
	return p.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (p *PaymentFormTypeRegular) EncodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode paymentFormTypeRegular#ba6d2f0f as nil")
	}
	if err := p.Invoice.Encode(b); err != nil {
		return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field invoice: %w", err)
	}
	b.PutInt53(p.PaymentProviderUserID)
	if p.PaymentProvider == nil {
		return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field payment_provider is nil")
	}
	if err := p.PaymentProvider.Encode(b); err != nil {
		return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field payment_provider: %w", err)
	}
	b.PutInt(len(p.AdditionalPaymentOptions))
	for idx, v := range p.AdditionalPaymentOptions {
		if err := v.EncodeBare(b); err != nil {
			return fmt.Errorf("unable to encode bare paymentFormTypeRegular#ba6d2f0f: field additional_payment_options element with index %d: %w", idx, err)
		}
	}
	if err := p.SavedOrderInfo.Encode(b); err != nil {
		return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field saved_order_info: %w", err)
	}
	b.PutInt(len(p.SavedCredentials))
	for idx, v := range p.SavedCredentials {
		if err := v.EncodeBare(b); err != nil {
			return fmt.Errorf("unable to encode bare paymentFormTypeRegular#ba6d2f0f: field saved_credentials element with index %d: %w", idx, err)
		}
	}
	b.PutBool(p.CanSaveCredentials)
	b.PutBool(p.NeedPassword)
	return nil
}

// Decode implements bin.Decoder.
func (p *PaymentFormTypeRegular) Decode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode paymentFormTypeRegular#ba6d2f0f to nil")
	}
	if err := b.ConsumeID(PaymentFormTypeRegularTypeID); err != nil {
		return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: %w", err)
	}
	return p.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (p *PaymentFormTypeRegular) DecodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode paymentFormTypeRegular#ba6d2f0f to nil")
	}
	{
		if err := p.Invoice.Decode(b); err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field invoice: %w", err)
		}
	}
	{
		value, err := b.Int53()
		if err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field payment_provider_user_id: %w", err)
		}
		p.PaymentProviderUserID = value
	}
	{
		value, err := DecodePaymentProvider(b)
		if err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field payment_provider: %w", err)
		}
		p.PaymentProvider = value
	}
	{
		headerLen, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field additional_payment_options: %w", err)
		}

		if headerLen > 0 {
			p.AdditionalPaymentOptions = make([]PaymentOption, 0, headerLen%bin.PreallocateLimit)
		}
		for idx := 0; idx < headerLen; idx++ {
			var value PaymentOption
			if err := value.DecodeBare(b); err != nil {
				return fmt.Errorf("unable to decode bare paymentFormTypeRegular#ba6d2f0f: field additional_payment_options: %w", err)
			}
			p.AdditionalPaymentOptions = append(p.AdditionalPaymentOptions, value)
		}
	}
	{
		if err := p.SavedOrderInfo.Decode(b); err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field saved_order_info: %w", err)
		}
	}
	{
		headerLen, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field saved_credentials: %w", err)
		}

		if headerLen > 0 {
			p.SavedCredentials = make([]SavedCredentials, 0, headerLen%bin.PreallocateLimit)
		}
		for idx := 0; idx < headerLen; idx++ {
			var value SavedCredentials
			if err := value.DecodeBare(b); err != nil {
				return fmt.Errorf("unable to decode bare paymentFormTypeRegular#ba6d2f0f: field saved_credentials: %w", err)
			}
			p.SavedCredentials = append(p.SavedCredentials, value)
		}
	}
	{
		value, err := b.Bool()
		if err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field can_save_credentials: %w", err)
		}
		p.CanSaveCredentials = value
	}
	{
		value, err := b.Bool()
		if err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field need_password: %w", err)
		}
		p.NeedPassword = value
	}
	return nil
}

// EncodeTDLibJSON implements tdjson.TDLibEncoder.
func (p *PaymentFormTypeRegular) EncodeTDLibJSON(b tdjson.Encoder) error {
	if p == nil {
		return fmt.Errorf("can't encode paymentFormTypeRegular#ba6d2f0f as nil")
	}
	b.ObjStart()
	b.PutID("paymentFormTypeRegular")
	b.Comma()
	b.FieldStart("invoice")
	if err := p.Invoice.EncodeTDLibJSON(b); err != nil {
		return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field invoice: %w", err)
	}
	b.Comma()
	b.FieldStart("payment_provider_user_id")
	b.PutInt53(p.PaymentProviderUserID)
	b.Comma()
	b.FieldStart("payment_provider")
	if p.PaymentProvider == nil {
		return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field payment_provider is nil")
	}
	if err := p.PaymentProvider.EncodeTDLibJSON(b); err != nil {
		return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field payment_provider: %w", err)
	}
	b.Comma()
	b.FieldStart("additional_payment_options")
	b.ArrStart()
	for idx, v := range p.AdditionalPaymentOptions {
		if err := v.EncodeTDLibJSON(b); err != nil {
			return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field additional_payment_options element with index %d: %w", idx, err)
		}
		b.Comma()
	}
	b.StripComma()
	b.ArrEnd()
	b.Comma()
	b.FieldStart("saved_order_info")
	if err := p.SavedOrderInfo.EncodeTDLibJSON(b); err != nil {
		return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field saved_order_info: %w", err)
	}
	b.Comma()
	b.FieldStart("saved_credentials")
	b.ArrStart()
	for idx, v := range p.SavedCredentials {
		if err := v.EncodeTDLibJSON(b); err != nil {
			return fmt.Errorf("unable to encode paymentFormTypeRegular#ba6d2f0f: field saved_credentials element with index %d: %w", idx, err)
		}
		b.Comma()
	}
	b.StripComma()
	b.ArrEnd()
	b.Comma()
	b.FieldStart("can_save_credentials")
	b.PutBool(p.CanSaveCredentials)
	b.Comma()
	b.FieldStart("need_password")
	b.PutBool(p.NeedPassword)
	b.Comma()
	b.StripComma()
	b.ObjEnd()
	return nil
}

// DecodeTDLibJSON implements tdjson.TDLibDecoder.
func (p *PaymentFormTypeRegular) DecodeTDLibJSON(b tdjson.Decoder) error {
	if p == nil {
		return fmt.Errorf("can't decode paymentFormTypeRegular#ba6d2f0f to nil")
	}

	return b.Obj(func(b tdjson.Decoder, key []byte) error {
		switch string(key) {
		case tdjson.TypeField:
			if err := b.ConsumeID("paymentFormTypeRegular"); err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: %w", err)
			}
		case "invoice":
			if err := p.Invoice.DecodeTDLibJSON(b); err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field invoice: %w", err)
			}
		case "payment_provider_user_id":
			value, err := b.Int53()
			if err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field payment_provider_user_id: %w", err)
			}
			p.PaymentProviderUserID = value
		case "payment_provider":
			value, err := DecodeTDLibJSONPaymentProvider(b)
			if err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field payment_provider: %w", err)
			}
			p.PaymentProvider = value
		case "additional_payment_options":
			if err := b.Arr(func(b tdjson.Decoder) error {
				var value PaymentOption
				if err := value.DecodeTDLibJSON(b); err != nil {
					return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field additional_payment_options: %w", err)
				}
				p.AdditionalPaymentOptions = append(p.AdditionalPaymentOptions, value)
				return nil
			}); err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field additional_payment_options: %w", err)
			}
		case "saved_order_info":
			if err := p.SavedOrderInfo.DecodeTDLibJSON(b); err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field saved_order_info: %w", err)
			}
		case "saved_credentials":
			if err := b.Arr(func(b tdjson.Decoder) error {
				var value SavedCredentials
				if err := value.DecodeTDLibJSON(b); err != nil {
					return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field saved_credentials: %w", err)
				}
				p.SavedCredentials = append(p.SavedCredentials, value)
				return nil
			}); err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field saved_credentials: %w", err)
			}
		case "can_save_credentials":
			value, err := b.Bool()
			if err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field can_save_credentials: %w", err)
			}
			p.CanSaveCredentials = value
		case "need_password":
			value, err := b.Bool()
			if err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeRegular#ba6d2f0f: field need_password: %w", err)
			}
			p.NeedPassword = value
		default:
			return b.Skip()
		}
		return nil
	})
}

// GetInvoice returns value of Invoice field.
func (p *PaymentFormTypeRegular) GetInvoice() (value Invoice) {
	if p == nil {
		return
	}
	return p.Invoice
}

// GetPaymentProviderUserID returns value of PaymentProviderUserID field.
func (p *PaymentFormTypeRegular) GetPaymentProviderUserID() (value int64) {
	if p == nil {
		return
	}
	return p.PaymentProviderUserID
}

// GetPaymentProvider returns value of PaymentProvider field.
func (p *PaymentFormTypeRegular) GetPaymentProvider() (value PaymentProviderClass) {
	if p == nil {
		return
	}
	return p.PaymentProvider
}

// GetAdditionalPaymentOptions returns value of AdditionalPaymentOptions field.
func (p *PaymentFormTypeRegular) GetAdditionalPaymentOptions() (value []PaymentOption) {
	if p == nil {
		return
	}
	return p.AdditionalPaymentOptions
}

// GetSavedOrderInfo returns value of SavedOrderInfo field.
func (p *PaymentFormTypeRegular) GetSavedOrderInfo() (value OrderInfo) {
	if p == nil {
		return
	}
	return p.SavedOrderInfo
}

// GetSavedCredentials returns value of SavedCredentials field.
func (p *PaymentFormTypeRegular) GetSavedCredentials() (value []SavedCredentials) {
	if p == nil {
		return
	}
	return p.SavedCredentials
}

// GetCanSaveCredentials returns value of CanSaveCredentials field.
func (p *PaymentFormTypeRegular) GetCanSaveCredentials() (value bool) {
	if p == nil {
		return
	}
	return p.CanSaveCredentials
}

// GetNeedPassword returns value of NeedPassword field.
func (p *PaymentFormTypeRegular) GetNeedPassword() (value bool) {
	if p == nil {
		return
	}
	return p.NeedPassword
}

// PaymentFormTypeStars represents TL type `paymentFormTypeStars#56b9d3d`.
type PaymentFormTypeStars struct {
	// Number of Telegram Stars that will be paid
	StarCount int64
}

// PaymentFormTypeStarsTypeID is TL type id of PaymentFormTypeStars.
const PaymentFormTypeStarsTypeID = 0x56b9d3d

// construct implements constructor of PaymentFormTypeClass.
func (p PaymentFormTypeStars) construct() PaymentFormTypeClass { return &p }

// Ensuring interfaces in compile-time for PaymentFormTypeStars.
var (
	_ bin.Encoder     = &PaymentFormTypeStars{}
	_ bin.Decoder     = &PaymentFormTypeStars{}
	_ bin.BareEncoder = &PaymentFormTypeStars{}
	_ bin.BareDecoder = &PaymentFormTypeStars{}

	_ PaymentFormTypeClass = &PaymentFormTypeStars{}
)

func (p *PaymentFormTypeStars) Zero() bool {
	if p == nil {
		return true
	}
	if !(p.StarCount == 0) {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (p *PaymentFormTypeStars) String() string {
	if p == nil {
		return "PaymentFormTypeStars(nil)"
	}
	type Alias PaymentFormTypeStars
	return fmt.Sprintf("PaymentFormTypeStars%+v", Alias(*p))
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*PaymentFormTypeStars) TypeID() uint32 {
	return PaymentFormTypeStarsTypeID
}

// TypeName returns name of type in TL schema.
func (*PaymentFormTypeStars) TypeName() string {
	return "paymentFormTypeStars"
}

// TypeInfo returns info about TL type.
func (p *PaymentFormTypeStars) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "paymentFormTypeStars",
		ID:   PaymentFormTypeStarsTypeID,
	}
	if p == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "StarCount",
			SchemaName: "star_count",
		},
	}
	return typ
}

// Encode implements bin.Encoder.
func (p *PaymentFormTypeStars) Encode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode paymentFormTypeStars#56b9d3d as nil")
	}
	b.PutID(PaymentFormTypeStarsTypeID)
	return p.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (p *PaymentFormTypeStars) EncodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode paymentFormTypeStars#56b9d3d as nil")
	}
	b.PutInt53(p.StarCount)
	return nil
}

// Decode implements bin.Decoder.
func (p *PaymentFormTypeStars) Decode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode paymentFormTypeStars#56b9d3d to nil")
	}
	if err := b.ConsumeID(PaymentFormTypeStarsTypeID); err != nil {
		return fmt.Errorf("unable to decode paymentFormTypeStars#56b9d3d: %w", err)
	}
	return p.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (p *PaymentFormTypeStars) DecodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode paymentFormTypeStars#56b9d3d to nil")
	}
	{
		value, err := b.Int53()
		if err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeStars#56b9d3d: field star_count: %w", err)
		}
		p.StarCount = value
	}
	return nil
}

// EncodeTDLibJSON implements tdjson.TDLibEncoder.
func (p *PaymentFormTypeStars) EncodeTDLibJSON(b tdjson.Encoder) error {
	if p == nil {
		return fmt.Errorf("can't encode paymentFormTypeStars#56b9d3d as nil")
	}
	b.ObjStart()
	b.PutID("paymentFormTypeStars")
	b.Comma()
	b.FieldStart("star_count")
	b.PutInt53(p.StarCount)
	b.Comma()
	b.StripComma()
	b.ObjEnd()
	return nil
}

// DecodeTDLibJSON implements tdjson.TDLibDecoder.
func (p *PaymentFormTypeStars) DecodeTDLibJSON(b tdjson.Decoder) error {
	if p == nil {
		return fmt.Errorf("can't decode paymentFormTypeStars#56b9d3d to nil")
	}

	return b.Obj(func(b tdjson.Decoder, key []byte) error {
		switch string(key) {
		case tdjson.TypeField:
			if err := b.ConsumeID("paymentFormTypeStars"); err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeStars#56b9d3d: %w", err)
			}
		case "star_count":
			value, err := b.Int53()
			if err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeStars#56b9d3d: field star_count: %w", err)
			}
			p.StarCount = value
		default:
			return b.Skip()
		}
		return nil
	})
}

// GetStarCount returns value of StarCount field.
func (p *PaymentFormTypeStars) GetStarCount() (value int64) {
	if p == nil {
		return
	}
	return p.StarCount
}

// PaymentFormTypeStarSubscription represents TL type `paymentFormTypeStarSubscription#102deb5b`.
type PaymentFormTypeStarSubscription struct {
	// Information about subscription plan
	Pricing StarSubscriptionPricing
}

// PaymentFormTypeStarSubscriptionTypeID is TL type id of PaymentFormTypeStarSubscription.
const PaymentFormTypeStarSubscriptionTypeID = 0x102deb5b

// construct implements constructor of PaymentFormTypeClass.
func (p PaymentFormTypeStarSubscription) construct() PaymentFormTypeClass { return &p }

// Ensuring interfaces in compile-time for PaymentFormTypeStarSubscription.
var (
	_ bin.Encoder     = &PaymentFormTypeStarSubscription{}
	_ bin.Decoder     = &PaymentFormTypeStarSubscription{}
	_ bin.BareEncoder = &PaymentFormTypeStarSubscription{}
	_ bin.BareDecoder = &PaymentFormTypeStarSubscription{}

	_ PaymentFormTypeClass = &PaymentFormTypeStarSubscription{}
)

func (p *PaymentFormTypeStarSubscription) Zero() bool {
	if p == nil {
		return true
	}
	if !(p.Pricing.Zero()) {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (p *PaymentFormTypeStarSubscription) String() string {
	if p == nil {
		return "PaymentFormTypeStarSubscription(nil)"
	}
	type Alias PaymentFormTypeStarSubscription
	return fmt.Sprintf("PaymentFormTypeStarSubscription%+v", Alias(*p))
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*PaymentFormTypeStarSubscription) TypeID() uint32 {
	return PaymentFormTypeStarSubscriptionTypeID
}

// TypeName returns name of type in TL schema.
func (*PaymentFormTypeStarSubscription) TypeName() string {
	return "paymentFormTypeStarSubscription"
}

// TypeInfo returns info about TL type.
func (p *PaymentFormTypeStarSubscription) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "paymentFormTypeStarSubscription",
		ID:   PaymentFormTypeStarSubscriptionTypeID,
	}
	if p == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Pricing",
			SchemaName: "pricing",
		},
	}
	return typ
}

// Encode implements bin.Encoder.
func (p *PaymentFormTypeStarSubscription) Encode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode paymentFormTypeStarSubscription#102deb5b as nil")
	}
	b.PutID(PaymentFormTypeStarSubscriptionTypeID)
	return p.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (p *PaymentFormTypeStarSubscription) EncodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode paymentFormTypeStarSubscription#102deb5b as nil")
	}
	if err := p.Pricing.Encode(b); err != nil {
		return fmt.Errorf("unable to encode paymentFormTypeStarSubscription#102deb5b: field pricing: %w", err)
	}
	return nil
}

// Decode implements bin.Decoder.
func (p *PaymentFormTypeStarSubscription) Decode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode paymentFormTypeStarSubscription#102deb5b to nil")
	}
	if err := b.ConsumeID(PaymentFormTypeStarSubscriptionTypeID); err != nil {
		return fmt.Errorf("unable to decode paymentFormTypeStarSubscription#102deb5b: %w", err)
	}
	return p.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (p *PaymentFormTypeStarSubscription) DecodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode paymentFormTypeStarSubscription#102deb5b to nil")
	}
	{
		if err := p.Pricing.Decode(b); err != nil {
			return fmt.Errorf("unable to decode paymentFormTypeStarSubscription#102deb5b: field pricing: %w", err)
		}
	}
	return nil
}

// EncodeTDLibJSON implements tdjson.TDLibEncoder.
func (p *PaymentFormTypeStarSubscription) EncodeTDLibJSON(b tdjson.Encoder) error {
	if p == nil {
		return fmt.Errorf("can't encode paymentFormTypeStarSubscription#102deb5b as nil")
	}
	b.ObjStart()
	b.PutID("paymentFormTypeStarSubscription")
	b.Comma()
	b.FieldStart("pricing")
	if err := p.Pricing.EncodeTDLibJSON(b); err != nil {
		return fmt.Errorf("unable to encode paymentFormTypeStarSubscription#102deb5b: field pricing: %w", err)
	}
	b.Comma()
	b.StripComma()
	b.ObjEnd()
	return nil
}

// DecodeTDLibJSON implements tdjson.TDLibDecoder.
func (p *PaymentFormTypeStarSubscription) DecodeTDLibJSON(b tdjson.Decoder) error {
	if p == nil {
		return fmt.Errorf("can't decode paymentFormTypeStarSubscription#102deb5b to nil")
	}

	return b.Obj(func(b tdjson.Decoder, key []byte) error {
		switch string(key) {
		case tdjson.TypeField:
			if err := b.ConsumeID("paymentFormTypeStarSubscription"); err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeStarSubscription#102deb5b: %w", err)
			}
		case "pricing":
			if err := p.Pricing.DecodeTDLibJSON(b); err != nil {
				return fmt.Errorf("unable to decode paymentFormTypeStarSubscription#102deb5b: field pricing: %w", err)
			}
		default:
			return b.Skip()
		}
		return nil
	})
}

// GetPricing returns value of Pricing field.
func (p *PaymentFormTypeStarSubscription) GetPricing() (value StarSubscriptionPricing) {
	if p == nil {
		return
	}
	return p.Pricing
}

// PaymentFormTypeClassName is schema name of PaymentFormTypeClass.
const PaymentFormTypeClassName = "PaymentFormType"

// PaymentFormTypeClass represents PaymentFormType generic type.
//
// Example:
//
//	g, err := tdapi.DecodePaymentFormType(buf)
//	if err != nil {
//	    panic(err)
//	}
//	switch v := g.(type) {
//	case *tdapi.PaymentFormTypeRegular: // paymentFormTypeRegular#ba6d2f0f
//	case *tdapi.PaymentFormTypeStars: // paymentFormTypeStars#56b9d3d
//	case *tdapi.PaymentFormTypeStarSubscription: // paymentFormTypeStarSubscription#102deb5b
//	default: panic(v)
//	}
type PaymentFormTypeClass interface {
	bin.Encoder
	bin.Decoder
	bin.BareEncoder
	bin.BareDecoder
	construct() PaymentFormTypeClass

	// TypeID returns type id in TL schema.
	//
	// See https://core.telegram.org/mtproto/TL-tl#remarks.
	TypeID() uint32
	// TypeName returns name of type in TL schema.
	TypeName() string
	// String implements fmt.Stringer.
	String() string
	// Zero returns true if current object has a zero value.
	Zero() bool

	EncodeTDLibJSON(b tdjson.Encoder) error
	DecodeTDLibJSON(b tdjson.Decoder) error
}

// DecodePaymentFormType implements binary de-serialization for PaymentFormTypeClass.
func DecodePaymentFormType(buf *bin.Buffer) (PaymentFormTypeClass, error) {
	id, err := buf.PeekID()
	if err != nil {
		return nil, err
	}
	switch id {
	case PaymentFormTypeRegularTypeID:
		// Decoding paymentFormTypeRegular#ba6d2f0f.
		v := PaymentFormTypeRegular{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PaymentFormTypeClass: %w", err)
		}
		return &v, nil
	case PaymentFormTypeStarsTypeID:
		// Decoding paymentFormTypeStars#56b9d3d.
		v := PaymentFormTypeStars{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PaymentFormTypeClass: %w", err)
		}
		return &v, nil
	case PaymentFormTypeStarSubscriptionTypeID:
		// Decoding paymentFormTypeStarSubscription#102deb5b.
		v := PaymentFormTypeStarSubscription{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PaymentFormTypeClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode PaymentFormTypeClass: %w", bin.NewUnexpectedID(id))
	}
}

// DecodeTDLibJSONPaymentFormType implements binary de-serialization for PaymentFormTypeClass.
func DecodeTDLibJSONPaymentFormType(buf tdjson.Decoder) (PaymentFormTypeClass, error) {
	id, err := buf.FindTypeID()
	if err != nil {
		return nil, err
	}
	switch id {
	case "paymentFormTypeRegular":
		// Decoding paymentFormTypeRegular#ba6d2f0f.
		v := PaymentFormTypeRegular{}
		if err := v.DecodeTDLibJSON(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PaymentFormTypeClass: %w", err)
		}
		return &v, nil
	case "paymentFormTypeStars":
		// Decoding paymentFormTypeStars#56b9d3d.
		v := PaymentFormTypeStars{}
		if err := v.DecodeTDLibJSON(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PaymentFormTypeClass: %w", err)
		}
		return &v, nil
	case "paymentFormTypeStarSubscription":
		// Decoding paymentFormTypeStarSubscription#102deb5b.
		v := PaymentFormTypeStarSubscription{}
		if err := v.DecodeTDLibJSON(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PaymentFormTypeClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode PaymentFormTypeClass: %w", tdjson.NewUnexpectedID(id))
	}
}

// PaymentFormType boxes the PaymentFormTypeClass providing a helper.
type PaymentFormTypeBox struct {
	PaymentFormType PaymentFormTypeClass
}

// Decode implements bin.Decoder for PaymentFormTypeBox.
func (b *PaymentFormTypeBox) Decode(buf *bin.Buffer) error {
	if b == nil {
		return fmt.Errorf("unable to decode PaymentFormTypeBox to nil")
	}
	v, err := DecodePaymentFormType(buf)
	if err != nil {
		return fmt.Errorf("unable to decode boxed value: %w", err)
	}
	b.PaymentFormType = v
	return nil
}

// Encode implements bin.Encode for PaymentFormTypeBox.
func (b *PaymentFormTypeBox) Encode(buf *bin.Buffer) error {
	if b == nil || b.PaymentFormType == nil {
		return fmt.Errorf("unable to encode PaymentFormTypeClass as nil")
	}
	return b.PaymentFormType.Encode(buf)
}

// DecodeTDLibJSON implements bin.Decoder for PaymentFormTypeBox.
func (b *PaymentFormTypeBox) DecodeTDLibJSON(buf tdjson.Decoder) error {
	if b == nil {
		return fmt.Errorf("unable to decode PaymentFormTypeBox to nil")
	}
	v, err := DecodeTDLibJSONPaymentFormType(buf)
	if err != nil {
		return fmt.Errorf("unable to decode boxed value: %w", err)
	}
	b.PaymentFormType = v
	return nil
}

// EncodeTDLibJSON implements bin.Encode for PaymentFormTypeBox.
func (b *PaymentFormTypeBox) EncodeTDLibJSON(buf tdjson.Encoder) error {
	if b == nil || b.PaymentFormType == nil {
		return fmt.Errorf("unable to encode PaymentFormTypeClass as nil")
	}
	return b.PaymentFormType.EncodeTDLibJSON(buf)
}
