// Code generated by gotdgen, DO NOT EDIT.

package tg

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{}
)

// InputStorePaymentPremiumSubscription represents TL type `inputStorePaymentPremiumSubscription#a6751e66`.
// Info about a Telegram Premium purchase
//
// See https://core.telegram.org/constructor/inputStorePaymentPremiumSubscription for reference.
type InputStorePaymentPremiumSubscription struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Pass true if this is a restore of a Telegram Premium purchase; only for the App Store
	Restore bool
	// Pass true if this is an upgrade from a monthly subscription to a yearly subscription;
	// only for App Store
	Upgrade bool
}

// InputStorePaymentPremiumSubscriptionTypeID is TL type id of InputStorePaymentPremiumSubscription.
const InputStorePaymentPremiumSubscriptionTypeID = 0xa6751e66

// construct implements constructor of InputStorePaymentPurposeClass.
func (i InputStorePaymentPremiumSubscription) construct() InputStorePaymentPurposeClass { return &i }

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

	_ InputStorePaymentPurposeClass = &InputStorePaymentPremiumSubscription{}
)

func (i *InputStorePaymentPremiumSubscription) Zero() bool {
	if i == nil {
		return true
	}
	if !(i.Flags.Zero()) {
		return false
	}
	if !(i.Restore == false) {
		return false
	}
	if !(i.Upgrade == false) {
		return false
	}

	return true
}

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

// FillFrom fills InputStorePaymentPremiumSubscription from given interface.
func (i *InputStorePaymentPremiumSubscription) FillFrom(from interface {
	GetRestore() (value bool)
	GetUpgrade() (value bool)
}) {
	i.Restore = from.GetRestore()
	i.Upgrade = from.GetUpgrade()
}

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

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

// TypeInfo returns info about TL type.
func (i *InputStorePaymentPremiumSubscription) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "inputStorePaymentPremiumSubscription",
		ID:   InputStorePaymentPremiumSubscriptionTypeID,
	}
	if i == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Restore",
			SchemaName: "restore",
			Null:       !i.Flags.Has(0),
		},
		{
			Name:       "Upgrade",
			SchemaName: "upgrade",
			Null:       !i.Flags.Has(1),
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (i *InputStorePaymentPremiumSubscription) SetFlags() {
	if !(i.Restore == false) {
		i.Flags.Set(0)
	}
	if !(i.Upgrade == false) {
		i.Flags.Set(1)
	}
}

// Encode implements bin.Encoder.
func (i *InputStorePaymentPremiumSubscription) Encode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentPremiumSubscription#a6751e66 as nil")
	}
	b.PutID(InputStorePaymentPremiumSubscriptionTypeID)
	return i.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (i *InputStorePaymentPremiumSubscription) EncodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentPremiumSubscription#a6751e66 as nil")
	}
	i.SetFlags()
	if err := i.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentPremiumSubscription#a6751e66: field flags: %w", err)
	}
	return nil
}

// Decode implements bin.Decoder.
func (i *InputStorePaymentPremiumSubscription) Decode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentPremiumSubscription#a6751e66 to nil")
	}
	if err := b.ConsumeID(InputStorePaymentPremiumSubscriptionTypeID); err != nil {
		return fmt.Errorf("unable to decode inputStorePaymentPremiumSubscription#a6751e66: %w", err)
	}
	return i.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (i *InputStorePaymentPremiumSubscription) DecodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentPremiumSubscription#a6751e66 to nil")
	}
	{
		if err := i.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumSubscription#a6751e66: field flags: %w", err)
		}
	}
	i.Restore = i.Flags.Has(0)
	i.Upgrade = i.Flags.Has(1)
	return nil
}

// SetRestore sets value of Restore conditional field.
func (i *InputStorePaymentPremiumSubscription) SetRestore(value bool) {
	if value {
		i.Flags.Set(0)
		i.Restore = true
	} else {
		i.Flags.Unset(0)
		i.Restore = false
	}
}

// GetRestore returns value of Restore conditional field.
func (i *InputStorePaymentPremiumSubscription) GetRestore() (value bool) {
	if i == nil {
		return
	}
	return i.Flags.Has(0)
}

// SetUpgrade sets value of Upgrade conditional field.
func (i *InputStorePaymentPremiumSubscription) SetUpgrade(value bool) {
	if value {
		i.Flags.Set(1)
		i.Upgrade = true
	} else {
		i.Flags.Unset(1)
		i.Upgrade = false
	}
}

// GetUpgrade returns value of Upgrade conditional field.
func (i *InputStorePaymentPremiumSubscription) GetUpgrade() (value bool) {
	if i == nil {
		return
	}
	return i.Flags.Has(1)
}

// InputStorePaymentGiftPremium represents TL type `inputStorePaymentGiftPremium#616f7fe8`.
// Info about a gifted Telegram Premium purchase
//
// See https://core.telegram.org/constructor/inputStorePaymentGiftPremium for reference.
type InputStorePaymentGiftPremium struct {
	// The user to which the Telegram Premium subscription was gifted
	UserID InputUserClass
	// Three-letter ISO 4217 currency¹ code
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments#supported-currencies
	Currency string
	// Price of the product in the smallest units of the currency (integer, not float/double)
	// For example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in
	// currencies.json¹, it shows the number of digits past the decimal point for each
	// currency (2 for the majority of currencies).
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments/currencies.json
	Amount int64
}

// InputStorePaymentGiftPremiumTypeID is TL type id of InputStorePaymentGiftPremium.
const InputStorePaymentGiftPremiumTypeID = 0x616f7fe8

// construct implements constructor of InputStorePaymentPurposeClass.
func (i InputStorePaymentGiftPremium) construct() InputStorePaymentPurposeClass { return &i }

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

	_ InputStorePaymentPurposeClass = &InputStorePaymentGiftPremium{}
)

func (i *InputStorePaymentGiftPremium) Zero() bool {
	if i == nil {
		return true
	}
	if !(i.UserID == nil) {
		return false
	}
	if !(i.Currency == "") {
		return false
	}
	if !(i.Amount == 0) {
		return false
	}

	return true
}

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

// FillFrom fills InputStorePaymentGiftPremium from given interface.
func (i *InputStorePaymentGiftPremium) FillFrom(from interface {
	GetUserID() (value InputUserClass)
	GetCurrency() (value string)
	GetAmount() (value int64)
}) {
	i.UserID = from.GetUserID()
	i.Currency = from.GetCurrency()
	i.Amount = from.GetAmount()
}

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

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

// TypeInfo returns info about TL type.
func (i *InputStorePaymentGiftPremium) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "inputStorePaymentGiftPremium",
		ID:   InputStorePaymentGiftPremiumTypeID,
	}
	if i == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "UserID",
			SchemaName: "user_id",
		},
		{
			Name:       "Currency",
			SchemaName: "currency",
		},
		{
			Name:       "Amount",
			SchemaName: "amount",
		},
	}
	return typ
}

// Encode implements bin.Encoder.
func (i *InputStorePaymentGiftPremium) Encode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentGiftPremium#616f7fe8 as nil")
	}
	b.PutID(InputStorePaymentGiftPremiumTypeID)
	return i.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (i *InputStorePaymentGiftPremium) EncodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentGiftPremium#616f7fe8 as nil")
	}
	if i.UserID == nil {
		return fmt.Errorf("unable to encode inputStorePaymentGiftPremium#616f7fe8: field user_id is nil")
	}
	if err := i.UserID.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentGiftPremium#616f7fe8: field user_id: %w", err)
	}
	b.PutString(i.Currency)
	b.PutLong(i.Amount)
	return nil
}

// Decode implements bin.Decoder.
func (i *InputStorePaymentGiftPremium) Decode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentGiftPremium#616f7fe8 to nil")
	}
	if err := b.ConsumeID(InputStorePaymentGiftPremiumTypeID); err != nil {
		return fmt.Errorf("unable to decode inputStorePaymentGiftPremium#616f7fe8: %w", err)
	}
	return i.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (i *InputStorePaymentGiftPremium) DecodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentGiftPremium#616f7fe8 to nil")
	}
	{
		value, err := DecodeInputUser(b)
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentGiftPremium#616f7fe8: field user_id: %w", err)
		}
		i.UserID = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentGiftPremium#616f7fe8: field currency: %w", err)
		}
		i.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentGiftPremium#616f7fe8: field amount: %w", err)
		}
		i.Amount = value
	}
	return nil
}

// GetUserID returns value of UserID field.
func (i *InputStorePaymentGiftPremium) GetUserID() (value InputUserClass) {
	if i == nil {
		return
	}
	return i.UserID
}

// GetCurrency returns value of Currency field.
func (i *InputStorePaymentGiftPremium) GetCurrency() (value string) {
	if i == nil {
		return
	}
	return i.Currency
}

// GetAmount returns value of Amount field.
func (i *InputStorePaymentGiftPremium) GetAmount() (value int64) {
	if i == nil {
		return
	}
	return i.Amount
}

// InputStorePaymentPremiumGiftCode represents TL type `inputStorePaymentPremiumGiftCode#fb790393`.
// Used to gift Telegram Premium¹ subscriptions only to some specific subscribers of a
// channel/supergroup or to some of our contacts, see here »² for more info on
// giveaways and gifts.
//
// Links:
//  1. https://core.telegram.org/api/premium
//  2. https://core.telegram.org/api/giveaways
//
// See https://core.telegram.org/constructor/inputStorePaymentPremiumGiftCode for reference.
type InputStorePaymentPremiumGiftCode struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// The users that will receive the Telegram Premium¹ subscriptions.
	//
	// Links:
	//  1) https://core.telegram.org/api/premium
	Users []InputUserClass
	// If set, the gifts will be sent on behalf of a channel/supergroup we are an admin of,
	// which will also assign some boosts¹ to it. Otherwise, the gift will be sent directly
	// from the currently logged in user, and we will gain some extra boost slots². See here
	// »³ for more info on giveaways and gifts.
	//
	// Links:
	//  1) https://core.telegram.org/api/boost
	//  2) https://core.telegram.org/api/boost
	//  3) https://core.telegram.org/api/giveaways
	//
	// Use SetBoostPeer and GetBoostPeer helpers.
	BoostPeer InputPeerClass
	// Three-letter ISO 4217 currency¹ code
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments#supported-currencies
	Currency string
	// Total price in the smallest units of the currency (integer, not float/double). For
	// example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in
	// currencies.json¹, it shows the number of digits past the decimal point for each
	// currency (2 for the majority of currencies).
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments/currencies.json
	Amount int64
	// Message attached with the gift
	//
	// Use SetMessage and GetMessage helpers.
	Message TextWithEntities
}

// InputStorePaymentPremiumGiftCodeTypeID is TL type id of InputStorePaymentPremiumGiftCode.
const InputStorePaymentPremiumGiftCodeTypeID = 0xfb790393

// construct implements constructor of InputStorePaymentPurposeClass.
func (i InputStorePaymentPremiumGiftCode) construct() InputStorePaymentPurposeClass { return &i }

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

	_ InputStorePaymentPurposeClass = &InputStorePaymentPremiumGiftCode{}
)

func (i *InputStorePaymentPremiumGiftCode) Zero() bool {
	if i == nil {
		return true
	}
	if !(i.Flags.Zero()) {
		return false
	}
	if !(i.Users == nil) {
		return false
	}
	if !(i.BoostPeer == nil) {
		return false
	}
	if !(i.Currency == "") {
		return false
	}
	if !(i.Amount == 0) {
		return false
	}
	if !(i.Message.Zero()) {
		return false
	}

	return true
}

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

// FillFrom fills InputStorePaymentPremiumGiftCode from given interface.
func (i *InputStorePaymentPremiumGiftCode) FillFrom(from interface {
	GetUsers() (value []InputUserClass)
	GetBoostPeer() (value InputPeerClass, ok bool)
	GetCurrency() (value string)
	GetAmount() (value int64)
	GetMessage() (value TextWithEntities, ok bool)
}) {
	i.Users = from.GetUsers()
	if val, ok := from.GetBoostPeer(); ok {
		i.BoostPeer = val
	}

	i.Currency = from.GetCurrency()
	i.Amount = from.GetAmount()
	if val, ok := from.GetMessage(); ok {
		i.Message = val
	}

}

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

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

// TypeInfo returns info about TL type.
func (i *InputStorePaymentPremiumGiftCode) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "inputStorePaymentPremiumGiftCode",
		ID:   InputStorePaymentPremiumGiftCodeTypeID,
	}
	if i == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Users",
			SchemaName: "users",
		},
		{
			Name:       "BoostPeer",
			SchemaName: "boost_peer",
			Null:       !i.Flags.Has(0),
		},
		{
			Name:       "Currency",
			SchemaName: "currency",
		},
		{
			Name:       "Amount",
			SchemaName: "amount",
		},
		{
			Name:       "Message",
			SchemaName: "message",
			Null:       !i.Flags.Has(1),
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (i *InputStorePaymentPremiumGiftCode) SetFlags() {
	if !(i.BoostPeer == nil) {
		i.Flags.Set(0)
	}
	if !(i.Message.Zero()) {
		i.Flags.Set(1)
	}
}

// Encode implements bin.Encoder.
func (i *InputStorePaymentPremiumGiftCode) Encode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentPremiumGiftCode#fb790393 as nil")
	}
	b.PutID(InputStorePaymentPremiumGiftCodeTypeID)
	return i.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (i *InputStorePaymentPremiumGiftCode) EncodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentPremiumGiftCode#fb790393 as nil")
	}
	i.SetFlags()
	if err := i.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentPremiumGiftCode#fb790393: field flags: %w", err)
	}
	b.PutVectorHeader(len(i.Users))
	for idx, v := range i.Users {
		if v == nil {
			return fmt.Errorf("unable to encode inputStorePaymentPremiumGiftCode#fb790393: field users element with index %d is nil", idx)
		}
		if err := v.Encode(b); err != nil {
			return fmt.Errorf("unable to encode inputStorePaymentPremiumGiftCode#fb790393: field users element with index %d: %w", idx, err)
		}
	}
	if i.Flags.Has(0) {
		if i.BoostPeer == nil {
			return fmt.Errorf("unable to encode inputStorePaymentPremiumGiftCode#fb790393: field boost_peer is nil")
		}
		if err := i.BoostPeer.Encode(b); err != nil {
			return fmt.Errorf("unable to encode inputStorePaymentPremiumGiftCode#fb790393: field boost_peer: %w", err)
		}
	}
	b.PutString(i.Currency)
	b.PutLong(i.Amount)
	if i.Flags.Has(1) {
		if err := i.Message.Encode(b); err != nil {
			return fmt.Errorf("unable to encode inputStorePaymentPremiumGiftCode#fb790393: field message: %w", err)
		}
	}
	return nil
}

// Decode implements bin.Decoder.
func (i *InputStorePaymentPremiumGiftCode) Decode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentPremiumGiftCode#fb790393 to nil")
	}
	if err := b.ConsumeID(InputStorePaymentPremiumGiftCodeTypeID); err != nil {
		return fmt.Errorf("unable to decode inputStorePaymentPremiumGiftCode#fb790393: %w", err)
	}
	return i.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (i *InputStorePaymentPremiumGiftCode) DecodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentPremiumGiftCode#fb790393 to nil")
	}
	{
		if err := i.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiftCode#fb790393: field flags: %w", err)
		}
	}
	{
		headerLen, err := b.VectorHeader()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiftCode#fb790393: field users: %w", err)
		}

		if headerLen > 0 {
			i.Users = make([]InputUserClass, 0, headerLen%bin.PreallocateLimit)
		}
		for idx := 0; idx < headerLen; idx++ {
			value, err := DecodeInputUser(b)
			if err != nil {
				return fmt.Errorf("unable to decode inputStorePaymentPremiumGiftCode#fb790393: field users: %w", err)
			}
			i.Users = append(i.Users, value)
		}
	}
	if i.Flags.Has(0) {
		value, err := DecodeInputPeer(b)
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiftCode#fb790393: field boost_peer: %w", err)
		}
		i.BoostPeer = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiftCode#fb790393: field currency: %w", err)
		}
		i.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiftCode#fb790393: field amount: %w", err)
		}
		i.Amount = value
	}
	if i.Flags.Has(1) {
		if err := i.Message.Decode(b); err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiftCode#fb790393: field message: %w", err)
		}
	}
	return nil
}

// GetUsers returns value of Users field.
func (i *InputStorePaymentPremiumGiftCode) GetUsers() (value []InputUserClass) {
	if i == nil {
		return
	}
	return i.Users
}

// SetBoostPeer sets value of BoostPeer conditional field.
func (i *InputStorePaymentPremiumGiftCode) SetBoostPeer(value InputPeerClass) {
	i.Flags.Set(0)
	i.BoostPeer = value
}

// GetBoostPeer returns value of BoostPeer conditional field and
// boolean which is true if field was set.
func (i *InputStorePaymentPremiumGiftCode) GetBoostPeer() (value InputPeerClass, ok bool) {
	if i == nil {
		return
	}
	if !i.Flags.Has(0) {
		return value, false
	}
	return i.BoostPeer, true
}

// GetCurrency returns value of Currency field.
func (i *InputStorePaymentPremiumGiftCode) GetCurrency() (value string) {
	if i == nil {
		return
	}
	return i.Currency
}

// GetAmount returns value of Amount field.
func (i *InputStorePaymentPremiumGiftCode) GetAmount() (value int64) {
	if i == nil {
		return
	}
	return i.Amount
}

// SetMessage sets value of Message conditional field.
func (i *InputStorePaymentPremiumGiftCode) SetMessage(value TextWithEntities) {
	i.Flags.Set(1)
	i.Message = value
}

// GetMessage returns value of Message conditional field and
// boolean which is true if field was set.
func (i *InputStorePaymentPremiumGiftCode) GetMessage() (value TextWithEntities, ok bool) {
	if i == nil {
		return
	}
	if !i.Flags.Has(1) {
		return value, false
	}
	return i.Message, true
}

// MapUsers returns field Users wrapped in InputUserClassArray helper.
func (i *InputStorePaymentPremiumGiftCode) MapUsers() (value InputUserClassArray) {
	return InputUserClassArray(i.Users)
}

// InputStorePaymentPremiumGiveaway represents TL type `inputStorePaymentPremiumGiveaway#160544ca`.
// Used to pay for a giveaway, see here »¹ for more info.
//
// Links:
//  1. https://core.telegram.org/api/giveaways
//
// See https://core.telegram.org/constructor/inputStorePaymentPremiumGiveaway for reference.
type InputStorePaymentPremiumGiveaway struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// If set, only new subscribers starting from the giveaway creation date will be able to
	// participate to the giveaway.
	OnlyNewSubscribers bool
	// If set, giveaway winners are public and will be listed in a
	// messageMediaGiveawayResults¹ message that will be automatically sent to the channel
	// once the giveaway ends.
	//
	// Links:
	//  1) https://core.telegram.org/constructor/messageMediaGiveawayResults
	WinnersAreVisible bool
	// The channel/supergroup starting the giveaway, that the user must join to participate,
	// that will receive the giveaway boosts¹; see here »² for more info on giveaways.
	//
	// Links:
	//  1) https://core.telegram.org/api/boost
	//  2) https://core.telegram.org/api/giveaways
	BoostPeer InputPeerClass
	// Additional channels that the user must join to participate to the giveaway can be
	// specified here.
	//
	// Use SetAdditionalPeers and GetAdditionalPeers helpers.
	AdditionalPeers []InputPeerClass
	// The set of users that can participate to the giveaway can be restricted by passing
	// here an explicit whitelist of up to giveaway_countries_max¹ countries, specified as
	// two-letter ISO 3166-1 alpha-2 country codes.
	//
	// Links:
	//  1) https://core.telegram.org/api/config#giveaway-countries-max
	//
	// Use SetCountriesISO2 and GetCountriesISO2 helpers.
	CountriesISO2 []string
	// Can contain a textual description of additional giveaway prizes.
	//
	// Use SetPrizeDescription and GetPrizeDescription helpers.
	PrizeDescription string
	// Random ID to avoid resending the giveaway
	RandomID int64
	// The end date of the giveaway, must be at most giveaway_period_max¹ seconds in the
	// future; see here »² for more info on giveaways.
	//
	// Links:
	//  1) https://core.telegram.org/api/config#giveaway-period-max
	//  2) https://core.telegram.org/api/giveaways
	UntilDate int
	// Three-letter ISO 4217 currency¹ code
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments#supported-currencies
	Currency string
	// Total price in the smallest units of the currency (integer, not float/double). For
	// example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in
	// currencies.json¹, it shows the number of digits past the decimal point for each
	// currency (2 for the majority of currencies).
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments/currencies.json
	Amount int64
}

// InputStorePaymentPremiumGiveawayTypeID is TL type id of InputStorePaymentPremiumGiveaway.
const InputStorePaymentPremiumGiveawayTypeID = 0x160544ca

// construct implements constructor of InputStorePaymentPurposeClass.
func (i InputStorePaymentPremiumGiveaway) construct() InputStorePaymentPurposeClass { return &i }

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

	_ InputStorePaymentPurposeClass = &InputStorePaymentPremiumGiveaway{}
)

func (i *InputStorePaymentPremiumGiveaway) Zero() bool {
	if i == nil {
		return true
	}
	if !(i.Flags.Zero()) {
		return false
	}
	if !(i.OnlyNewSubscribers == false) {
		return false
	}
	if !(i.WinnersAreVisible == false) {
		return false
	}
	if !(i.BoostPeer == nil) {
		return false
	}
	if !(i.AdditionalPeers == nil) {
		return false
	}
	if !(i.CountriesISO2 == nil) {
		return false
	}
	if !(i.PrizeDescription == "") {
		return false
	}
	if !(i.RandomID == 0) {
		return false
	}
	if !(i.UntilDate == 0) {
		return false
	}
	if !(i.Currency == "") {
		return false
	}
	if !(i.Amount == 0) {
		return false
	}

	return true
}

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

// FillFrom fills InputStorePaymentPremiumGiveaway from given interface.
func (i *InputStorePaymentPremiumGiveaway) FillFrom(from interface {
	GetOnlyNewSubscribers() (value bool)
	GetWinnersAreVisible() (value bool)
	GetBoostPeer() (value InputPeerClass)
	GetAdditionalPeers() (value []InputPeerClass, ok bool)
	GetCountriesISO2() (value []string, ok bool)
	GetPrizeDescription() (value string, ok bool)
	GetRandomID() (value int64)
	GetUntilDate() (value int)
	GetCurrency() (value string)
	GetAmount() (value int64)
}) {
	i.OnlyNewSubscribers = from.GetOnlyNewSubscribers()
	i.WinnersAreVisible = from.GetWinnersAreVisible()
	i.BoostPeer = from.GetBoostPeer()
	if val, ok := from.GetAdditionalPeers(); ok {
		i.AdditionalPeers = val
	}

	if val, ok := from.GetCountriesISO2(); ok {
		i.CountriesISO2 = val
	}

	if val, ok := from.GetPrizeDescription(); ok {
		i.PrizeDescription = val
	}

	i.RandomID = from.GetRandomID()
	i.UntilDate = from.GetUntilDate()
	i.Currency = from.GetCurrency()
	i.Amount = from.GetAmount()
}

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

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

// TypeInfo returns info about TL type.
func (i *InputStorePaymentPremiumGiveaway) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "inputStorePaymentPremiumGiveaway",
		ID:   InputStorePaymentPremiumGiveawayTypeID,
	}
	if i == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "OnlyNewSubscribers",
			SchemaName: "only_new_subscribers",
			Null:       !i.Flags.Has(0),
		},
		{
			Name:       "WinnersAreVisible",
			SchemaName: "winners_are_visible",
			Null:       !i.Flags.Has(3),
		},
		{
			Name:       "BoostPeer",
			SchemaName: "boost_peer",
		},
		{
			Name:       "AdditionalPeers",
			SchemaName: "additional_peers",
			Null:       !i.Flags.Has(1),
		},
		{
			Name:       "CountriesISO2",
			SchemaName: "countries_iso2",
			Null:       !i.Flags.Has(2),
		},
		{
			Name:       "PrizeDescription",
			SchemaName: "prize_description",
			Null:       !i.Flags.Has(4),
		},
		{
			Name:       "RandomID",
			SchemaName: "random_id",
		},
		{
			Name:       "UntilDate",
			SchemaName: "until_date",
		},
		{
			Name:       "Currency",
			SchemaName: "currency",
		},
		{
			Name:       "Amount",
			SchemaName: "amount",
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (i *InputStorePaymentPremiumGiveaway) SetFlags() {
	if !(i.OnlyNewSubscribers == false) {
		i.Flags.Set(0)
	}
	if !(i.WinnersAreVisible == false) {
		i.Flags.Set(3)
	}
	if !(i.AdditionalPeers == nil) {
		i.Flags.Set(1)
	}
	if !(i.CountriesISO2 == nil) {
		i.Flags.Set(2)
	}
	if !(i.PrizeDescription == "") {
		i.Flags.Set(4)
	}
}

// Encode implements bin.Encoder.
func (i *InputStorePaymentPremiumGiveaway) Encode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentPremiumGiveaway#160544ca as nil")
	}
	b.PutID(InputStorePaymentPremiumGiveawayTypeID)
	return i.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (i *InputStorePaymentPremiumGiveaway) EncodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentPremiumGiveaway#160544ca as nil")
	}
	i.SetFlags()
	if err := i.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentPremiumGiveaway#160544ca: field flags: %w", err)
	}
	if i.BoostPeer == nil {
		return fmt.Errorf("unable to encode inputStorePaymentPremiumGiveaway#160544ca: field boost_peer is nil")
	}
	if err := i.BoostPeer.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentPremiumGiveaway#160544ca: field boost_peer: %w", err)
	}
	if i.Flags.Has(1) {
		b.PutVectorHeader(len(i.AdditionalPeers))
		for idx, v := range i.AdditionalPeers {
			if v == nil {
				return fmt.Errorf("unable to encode inputStorePaymentPremiumGiveaway#160544ca: field additional_peers element with index %d is nil", idx)
			}
			if err := v.Encode(b); err != nil {
				return fmt.Errorf("unable to encode inputStorePaymentPremiumGiveaway#160544ca: field additional_peers element with index %d: %w", idx, err)
			}
		}
	}
	if i.Flags.Has(2) {
		b.PutVectorHeader(len(i.CountriesISO2))
		for _, v := range i.CountriesISO2 {
			b.PutString(v)
		}
	}
	if i.Flags.Has(4) {
		b.PutString(i.PrizeDescription)
	}
	b.PutLong(i.RandomID)
	b.PutInt(i.UntilDate)
	b.PutString(i.Currency)
	b.PutLong(i.Amount)
	return nil
}

// Decode implements bin.Decoder.
func (i *InputStorePaymentPremiumGiveaway) Decode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentPremiumGiveaway#160544ca to nil")
	}
	if err := b.ConsumeID(InputStorePaymentPremiumGiveawayTypeID); err != nil {
		return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: %w", err)
	}
	return i.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (i *InputStorePaymentPremiumGiveaway) DecodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentPremiumGiveaway#160544ca to nil")
	}
	{
		if err := i.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field flags: %w", err)
		}
	}
	i.OnlyNewSubscribers = i.Flags.Has(0)
	i.WinnersAreVisible = i.Flags.Has(3)
	{
		value, err := DecodeInputPeer(b)
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field boost_peer: %w", err)
		}
		i.BoostPeer = value
	}
	if i.Flags.Has(1) {
		headerLen, err := b.VectorHeader()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field additional_peers: %w", err)
		}

		if headerLen > 0 {
			i.AdditionalPeers = make([]InputPeerClass, 0, headerLen%bin.PreallocateLimit)
		}
		for idx := 0; idx < headerLen; idx++ {
			value, err := DecodeInputPeer(b)
			if err != nil {
				return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field additional_peers: %w", err)
			}
			i.AdditionalPeers = append(i.AdditionalPeers, value)
		}
	}
	if i.Flags.Has(2) {
		headerLen, err := b.VectorHeader()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field countries_iso2: %w", err)
		}

		if headerLen > 0 {
			i.CountriesISO2 = make([]string, 0, headerLen%bin.PreallocateLimit)
		}
		for idx := 0; idx < headerLen; idx++ {
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field countries_iso2: %w", err)
			}
			i.CountriesISO2 = append(i.CountriesISO2, value)
		}
	}
	if i.Flags.Has(4) {
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field prize_description: %w", err)
		}
		i.PrizeDescription = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field random_id: %w", err)
		}
		i.RandomID = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field until_date: %w", err)
		}
		i.UntilDate = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field currency: %w", err)
		}
		i.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentPremiumGiveaway#160544ca: field amount: %w", err)
		}
		i.Amount = value
	}
	return nil
}

// SetOnlyNewSubscribers sets value of OnlyNewSubscribers conditional field.
func (i *InputStorePaymentPremiumGiveaway) SetOnlyNewSubscribers(value bool) {
	if value {
		i.Flags.Set(0)
		i.OnlyNewSubscribers = true
	} else {
		i.Flags.Unset(0)
		i.OnlyNewSubscribers = false
	}
}

// GetOnlyNewSubscribers returns value of OnlyNewSubscribers conditional field.
func (i *InputStorePaymentPremiumGiveaway) GetOnlyNewSubscribers() (value bool) {
	if i == nil {
		return
	}
	return i.Flags.Has(0)
}

// SetWinnersAreVisible sets value of WinnersAreVisible conditional field.
func (i *InputStorePaymentPremiumGiveaway) SetWinnersAreVisible(value bool) {
	if value {
		i.Flags.Set(3)
		i.WinnersAreVisible = true
	} else {
		i.Flags.Unset(3)
		i.WinnersAreVisible = false
	}
}

// GetWinnersAreVisible returns value of WinnersAreVisible conditional field.
func (i *InputStorePaymentPremiumGiveaway) GetWinnersAreVisible() (value bool) {
	if i == nil {
		return
	}
	return i.Flags.Has(3)
}

// GetBoostPeer returns value of BoostPeer field.
func (i *InputStorePaymentPremiumGiveaway) GetBoostPeer() (value InputPeerClass) {
	if i == nil {
		return
	}
	return i.BoostPeer
}

// SetAdditionalPeers sets value of AdditionalPeers conditional field.
func (i *InputStorePaymentPremiumGiveaway) SetAdditionalPeers(value []InputPeerClass) {
	i.Flags.Set(1)
	i.AdditionalPeers = value
}

// GetAdditionalPeers returns value of AdditionalPeers conditional field and
// boolean which is true if field was set.
func (i *InputStorePaymentPremiumGiveaway) GetAdditionalPeers() (value []InputPeerClass, ok bool) {
	if i == nil {
		return
	}
	if !i.Flags.Has(1) {
		return value, false
	}
	return i.AdditionalPeers, true
}

// SetCountriesISO2 sets value of CountriesISO2 conditional field.
func (i *InputStorePaymentPremiumGiveaway) SetCountriesISO2(value []string) {
	i.Flags.Set(2)
	i.CountriesISO2 = value
}

// GetCountriesISO2 returns value of CountriesISO2 conditional field and
// boolean which is true if field was set.
func (i *InputStorePaymentPremiumGiveaway) GetCountriesISO2() (value []string, ok bool) {
	if i == nil {
		return
	}
	if !i.Flags.Has(2) {
		return value, false
	}
	return i.CountriesISO2, true
}

// SetPrizeDescription sets value of PrizeDescription conditional field.
func (i *InputStorePaymentPremiumGiveaway) SetPrizeDescription(value string) {
	i.Flags.Set(4)
	i.PrizeDescription = value
}

// GetPrizeDescription returns value of PrizeDescription conditional field and
// boolean which is true if field was set.
func (i *InputStorePaymentPremiumGiveaway) GetPrizeDescription() (value string, ok bool) {
	if i == nil {
		return
	}
	if !i.Flags.Has(4) {
		return value, false
	}
	return i.PrizeDescription, true
}

// GetRandomID returns value of RandomID field.
func (i *InputStorePaymentPremiumGiveaway) GetRandomID() (value int64) {
	if i == nil {
		return
	}
	return i.RandomID
}

// GetUntilDate returns value of UntilDate field.
func (i *InputStorePaymentPremiumGiveaway) GetUntilDate() (value int) {
	if i == nil {
		return
	}
	return i.UntilDate
}

// GetCurrency returns value of Currency field.
func (i *InputStorePaymentPremiumGiveaway) GetCurrency() (value string) {
	if i == nil {
		return
	}
	return i.Currency
}

// GetAmount returns value of Amount field.
func (i *InputStorePaymentPremiumGiveaway) GetAmount() (value int64) {
	if i == nil {
		return
	}
	return i.Amount
}

// MapAdditionalPeers returns field AdditionalPeers wrapped in InputPeerClassArray helper.
func (i *InputStorePaymentPremiumGiveaway) MapAdditionalPeers() (value InputPeerClassArray, ok bool) {
	if !i.Flags.Has(1) {
		return value, false
	}
	return InputPeerClassArray(i.AdditionalPeers), true
}

// InputStorePaymentStarsTopup represents TL type `inputStorePaymentStarsTopup#f9a2a6cb`.
// Used to top up the Telegram Stars balance¹ of the current account.
//
// Links:
//  1. https://core.telegram.org/api/stars
//
// See https://core.telegram.org/constructor/inputStorePaymentStarsTopup for reference.
type InputStorePaymentStarsTopup struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Amount of stars to topup
	Stars int64
	// Three-letter ISO 4217 currency¹ code
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments#supported-currencies
	Currency string
	// Total price in the smallest units of the currency (integer, not float/double). For
	// example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in
	// currencies.json¹, it shows the number of digits past the decimal point for each
	// currency (2 for the majority of currencies).
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments/currencies.json
	Amount int64
	// Should be populated with the peer where the topup process was initiated due to low
	// funds (i.e. a bot for bot payments, a channel for paid media/reactions, etc); leave
	// this flag unpopulated if the topup flow was not initated when attempting to spend more
	// Stars than currently available on the account's balance.
	//
	// Use SetSpendPurposePeer and GetSpendPurposePeer helpers.
	SpendPurposePeer InputPeerClass
}

// InputStorePaymentStarsTopupTypeID is TL type id of InputStorePaymentStarsTopup.
const InputStorePaymentStarsTopupTypeID = 0xf9a2a6cb

// construct implements constructor of InputStorePaymentPurposeClass.
func (i InputStorePaymentStarsTopup) construct() InputStorePaymentPurposeClass { return &i }

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

	_ InputStorePaymentPurposeClass = &InputStorePaymentStarsTopup{}
)

func (i *InputStorePaymentStarsTopup) Zero() bool {
	if i == nil {
		return true
	}
	if !(i.Flags.Zero()) {
		return false
	}
	if !(i.Stars == 0) {
		return false
	}
	if !(i.Currency == "") {
		return false
	}
	if !(i.Amount == 0) {
		return false
	}
	if !(i.SpendPurposePeer == nil) {
		return false
	}

	return true
}

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

// FillFrom fills InputStorePaymentStarsTopup from given interface.
func (i *InputStorePaymentStarsTopup) FillFrom(from interface {
	GetStars() (value int64)
	GetCurrency() (value string)
	GetAmount() (value int64)
	GetSpendPurposePeer() (value InputPeerClass, ok bool)
}) {
	i.Stars = from.GetStars()
	i.Currency = from.GetCurrency()
	i.Amount = from.GetAmount()
	if val, ok := from.GetSpendPurposePeer(); ok {
		i.SpendPurposePeer = val
	}

}

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

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

// TypeInfo returns info about TL type.
func (i *InputStorePaymentStarsTopup) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "inputStorePaymentStarsTopup",
		ID:   InputStorePaymentStarsTopupTypeID,
	}
	if i == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Stars",
			SchemaName: "stars",
		},
		{
			Name:       "Currency",
			SchemaName: "currency",
		},
		{
			Name:       "Amount",
			SchemaName: "amount",
		},
		{
			Name:       "SpendPurposePeer",
			SchemaName: "spend_purpose_peer",
			Null:       !i.Flags.Has(0),
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (i *InputStorePaymentStarsTopup) SetFlags() {
	if !(i.SpendPurposePeer == nil) {
		i.Flags.Set(0)
	}
}

// Encode implements bin.Encoder.
func (i *InputStorePaymentStarsTopup) Encode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentStarsTopup#f9a2a6cb as nil")
	}
	b.PutID(InputStorePaymentStarsTopupTypeID)
	return i.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (i *InputStorePaymentStarsTopup) EncodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentStarsTopup#f9a2a6cb as nil")
	}
	i.SetFlags()
	if err := i.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentStarsTopup#f9a2a6cb: field flags: %w", err)
	}
	b.PutLong(i.Stars)
	b.PutString(i.Currency)
	b.PutLong(i.Amount)
	if i.Flags.Has(0) {
		if i.SpendPurposePeer == nil {
			return fmt.Errorf("unable to encode inputStorePaymentStarsTopup#f9a2a6cb: field spend_purpose_peer is nil")
		}
		if err := i.SpendPurposePeer.Encode(b); err != nil {
			return fmt.Errorf("unable to encode inputStorePaymentStarsTopup#f9a2a6cb: field spend_purpose_peer: %w", err)
		}
	}
	return nil
}

// Decode implements bin.Decoder.
func (i *InputStorePaymentStarsTopup) Decode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentStarsTopup#f9a2a6cb to nil")
	}
	if err := b.ConsumeID(InputStorePaymentStarsTopupTypeID); err != nil {
		return fmt.Errorf("unable to decode inputStorePaymentStarsTopup#f9a2a6cb: %w", err)
	}
	return i.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (i *InputStorePaymentStarsTopup) DecodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentStarsTopup#f9a2a6cb to nil")
	}
	{
		if err := i.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsTopup#f9a2a6cb: field flags: %w", err)
		}
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsTopup#f9a2a6cb: field stars: %w", err)
		}
		i.Stars = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsTopup#f9a2a6cb: field currency: %w", err)
		}
		i.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsTopup#f9a2a6cb: field amount: %w", err)
		}
		i.Amount = value
	}
	if i.Flags.Has(0) {
		value, err := DecodeInputPeer(b)
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsTopup#f9a2a6cb: field spend_purpose_peer: %w", err)
		}
		i.SpendPurposePeer = value
	}
	return nil
}

// GetStars returns value of Stars field.
func (i *InputStorePaymentStarsTopup) GetStars() (value int64) {
	if i == nil {
		return
	}
	return i.Stars
}

// GetCurrency returns value of Currency field.
func (i *InputStorePaymentStarsTopup) GetCurrency() (value string) {
	if i == nil {
		return
	}
	return i.Currency
}

// GetAmount returns value of Amount field.
func (i *InputStorePaymentStarsTopup) GetAmount() (value int64) {
	if i == nil {
		return
	}
	return i.Amount
}

// SetSpendPurposePeer sets value of SpendPurposePeer conditional field.
func (i *InputStorePaymentStarsTopup) SetSpendPurposePeer(value InputPeerClass) {
	i.Flags.Set(0)
	i.SpendPurposePeer = value
}

// GetSpendPurposePeer returns value of SpendPurposePeer conditional field and
// boolean which is true if field was set.
func (i *InputStorePaymentStarsTopup) GetSpendPurposePeer() (value InputPeerClass, ok bool) {
	if i == nil {
		return
	}
	if !i.Flags.Has(0) {
		return value, false
	}
	return i.SpendPurposePeer, true
}

// InputStorePaymentStarsGift represents TL type `inputStorePaymentStarsGift#1d741ef7`.
// Used to gift Telegram Stars¹ to a friend.
//
// Links:
//  1. https://core.telegram.org/api/stars
//
// See https://core.telegram.org/constructor/inputStorePaymentStarsGift for reference.
type InputStorePaymentStarsGift struct {
	// The user to which the stars should be gifted.
	UserID InputUserClass
	// Amount of stars to gift
	Stars int64
	// Three-letter ISO 4217 currency¹ code
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments#supported-currencies
	Currency string
	// Total price in the smallest units of the currency (integer, not float/double). For
	// example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in
	// currencies.json¹, it shows the number of digits past the decimal point for each
	// currency (2 for the majority of currencies).
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments/currencies.json
	Amount int64
}

// InputStorePaymentStarsGiftTypeID is TL type id of InputStorePaymentStarsGift.
const InputStorePaymentStarsGiftTypeID = 0x1d741ef7

// construct implements constructor of InputStorePaymentPurposeClass.
func (i InputStorePaymentStarsGift) construct() InputStorePaymentPurposeClass { return &i }

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

	_ InputStorePaymentPurposeClass = &InputStorePaymentStarsGift{}
)

func (i *InputStorePaymentStarsGift) Zero() bool {
	if i == nil {
		return true
	}
	if !(i.UserID == nil) {
		return false
	}
	if !(i.Stars == 0) {
		return false
	}
	if !(i.Currency == "") {
		return false
	}
	if !(i.Amount == 0) {
		return false
	}

	return true
}

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

// FillFrom fills InputStorePaymentStarsGift from given interface.
func (i *InputStorePaymentStarsGift) FillFrom(from interface {
	GetUserID() (value InputUserClass)
	GetStars() (value int64)
	GetCurrency() (value string)
	GetAmount() (value int64)
}) {
	i.UserID = from.GetUserID()
	i.Stars = from.GetStars()
	i.Currency = from.GetCurrency()
	i.Amount = from.GetAmount()
}

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

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

// TypeInfo returns info about TL type.
func (i *InputStorePaymentStarsGift) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "inputStorePaymentStarsGift",
		ID:   InputStorePaymentStarsGiftTypeID,
	}
	if i == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "UserID",
			SchemaName: "user_id",
		},
		{
			Name:       "Stars",
			SchemaName: "stars",
		},
		{
			Name:       "Currency",
			SchemaName: "currency",
		},
		{
			Name:       "Amount",
			SchemaName: "amount",
		},
	}
	return typ
}

// Encode implements bin.Encoder.
func (i *InputStorePaymentStarsGift) Encode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentStarsGift#1d741ef7 as nil")
	}
	b.PutID(InputStorePaymentStarsGiftTypeID)
	return i.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (i *InputStorePaymentStarsGift) EncodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentStarsGift#1d741ef7 as nil")
	}
	if i.UserID == nil {
		return fmt.Errorf("unable to encode inputStorePaymentStarsGift#1d741ef7: field user_id is nil")
	}
	if err := i.UserID.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentStarsGift#1d741ef7: field user_id: %w", err)
	}
	b.PutLong(i.Stars)
	b.PutString(i.Currency)
	b.PutLong(i.Amount)
	return nil
}

// Decode implements bin.Decoder.
func (i *InputStorePaymentStarsGift) Decode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentStarsGift#1d741ef7 to nil")
	}
	if err := b.ConsumeID(InputStorePaymentStarsGiftTypeID); err != nil {
		return fmt.Errorf("unable to decode inputStorePaymentStarsGift#1d741ef7: %w", err)
	}
	return i.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (i *InputStorePaymentStarsGift) DecodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentStarsGift#1d741ef7 to nil")
	}
	{
		value, err := DecodeInputUser(b)
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGift#1d741ef7: field user_id: %w", err)
		}
		i.UserID = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGift#1d741ef7: field stars: %w", err)
		}
		i.Stars = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGift#1d741ef7: field currency: %w", err)
		}
		i.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGift#1d741ef7: field amount: %w", err)
		}
		i.Amount = value
	}
	return nil
}

// GetUserID returns value of UserID field.
func (i *InputStorePaymentStarsGift) GetUserID() (value InputUserClass) {
	if i == nil {
		return
	}
	return i.UserID
}

// GetStars returns value of Stars field.
func (i *InputStorePaymentStarsGift) GetStars() (value int64) {
	if i == nil {
		return
	}
	return i.Stars
}

// GetCurrency returns value of Currency field.
func (i *InputStorePaymentStarsGift) GetCurrency() (value string) {
	if i == nil {
		return
	}
	return i.Currency
}

// GetAmount returns value of Amount field.
func (i *InputStorePaymentStarsGift) GetAmount() (value int64) {
	if i == nil {
		return
	}
	return i.Amount
}

// InputStorePaymentStarsGiveaway represents TL type `inputStorePaymentStarsGiveaway#751f08fa`.
// Used to pay for a star giveaway, see here »¹ for more info.
//
// Links:
//  1. https://core.telegram.org/api/giveaways#star-giveaways
//
// See https://core.telegram.org/constructor/inputStorePaymentStarsGiveaway for reference.
type InputStorePaymentStarsGiveaway struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// If set, only new subscribers starting from the giveaway creation date will be able to
	// participate to the giveaway.
	OnlyNewSubscribers bool
	// If set, giveaway winners are public and will be listed in a
	// messageMediaGiveawayResults¹ message that will be automatically sent to the channel
	// once the giveaway ends.
	//
	// Links:
	//  1) https://core.telegram.org/constructor/messageMediaGiveawayResults
	WinnersAreVisible bool
	// Total number of Telegram Stars being given away (each user will receive stars/users
	// stars).
	Stars int64
	// The channel/supergroup starting the giveaway, that the user must join to participate,
	// that will receive the giveaway boosts¹; see here »² for more info on giveaways.
	//
	// Links:
	//  1) https://core.telegram.org/api/boost
	//  2) https://core.telegram.org/api/giveaways
	BoostPeer InputPeerClass
	// Additional channels that the user must join to participate to the giveaway can be
	// specified here.
	//
	// Use SetAdditionalPeers and GetAdditionalPeers helpers.
	AdditionalPeers []InputPeerClass
	// The set of users that can participate to the giveaway can be restricted by passing
	// here an explicit whitelist of up to giveaway_countries_max¹ countries, specified as
	// two-letter ISO 3166-1 alpha-2 country codes.
	//
	// Links:
	//  1) https://core.telegram.org/api/config#giveaway-countries-max
	//
	// Use SetCountriesISO2 and GetCountriesISO2 helpers.
	CountriesISO2 []string
	// Can contain a textual description of additional giveaway prizes.
	//
	// Use SetPrizeDescription and GetPrizeDescription helpers.
	PrizeDescription string
	// Random ID to avoid resending the giveaway
	RandomID int64
	// The end date of the giveaway, must be at most giveaway_period_max¹ seconds in the
	// future; see here »² for more info on giveaways.
	//
	// Links:
	//  1) https://core.telegram.org/api/config#giveaway-period-max
	//  2) https://core.telegram.org/api/giveaways
	UntilDate int
	// Three-letter ISO 4217 currency¹ code
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments#supported-currencies
	Currency string
	// Total price in the smallest units of the currency (integer, not float/double). For
	// example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in
	// currencies.json¹, it shows the number of digits past the decimal point for each
	// currency (2 for the majority of currencies).
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments/currencies.json
	Amount int64
	// Number of winners.
	Users int
}

// InputStorePaymentStarsGiveawayTypeID is TL type id of InputStorePaymentStarsGiveaway.
const InputStorePaymentStarsGiveawayTypeID = 0x751f08fa

// construct implements constructor of InputStorePaymentPurposeClass.
func (i InputStorePaymentStarsGiveaway) construct() InputStorePaymentPurposeClass { return &i }

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

	_ InputStorePaymentPurposeClass = &InputStorePaymentStarsGiveaway{}
)

func (i *InputStorePaymentStarsGiveaway) Zero() bool {
	if i == nil {
		return true
	}
	if !(i.Flags.Zero()) {
		return false
	}
	if !(i.OnlyNewSubscribers == false) {
		return false
	}
	if !(i.WinnersAreVisible == false) {
		return false
	}
	if !(i.Stars == 0) {
		return false
	}
	if !(i.BoostPeer == nil) {
		return false
	}
	if !(i.AdditionalPeers == nil) {
		return false
	}
	if !(i.CountriesISO2 == nil) {
		return false
	}
	if !(i.PrizeDescription == "") {
		return false
	}
	if !(i.RandomID == 0) {
		return false
	}
	if !(i.UntilDate == 0) {
		return false
	}
	if !(i.Currency == "") {
		return false
	}
	if !(i.Amount == 0) {
		return false
	}
	if !(i.Users == 0) {
		return false
	}

	return true
}

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

// FillFrom fills InputStorePaymentStarsGiveaway from given interface.
func (i *InputStorePaymentStarsGiveaway) FillFrom(from interface {
	GetOnlyNewSubscribers() (value bool)
	GetWinnersAreVisible() (value bool)
	GetStars() (value int64)
	GetBoostPeer() (value InputPeerClass)
	GetAdditionalPeers() (value []InputPeerClass, ok bool)
	GetCountriesISO2() (value []string, ok bool)
	GetPrizeDescription() (value string, ok bool)
	GetRandomID() (value int64)
	GetUntilDate() (value int)
	GetCurrency() (value string)
	GetAmount() (value int64)
	GetUsers() (value int)
}) {
	i.OnlyNewSubscribers = from.GetOnlyNewSubscribers()
	i.WinnersAreVisible = from.GetWinnersAreVisible()
	i.Stars = from.GetStars()
	i.BoostPeer = from.GetBoostPeer()
	if val, ok := from.GetAdditionalPeers(); ok {
		i.AdditionalPeers = val
	}

	if val, ok := from.GetCountriesISO2(); ok {
		i.CountriesISO2 = val
	}

	if val, ok := from.GetPrizeDescription(); ok {
		i.PrizeDescription = val
	}

	i.RandomID = from.GetRandomID()
	i.UntilDate = from.GetUntilDate()
	i.Currency = from.GetCurrency()
	i.Amount = from.GetAmount()
	i.Users = from.GetUsers()
}

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

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

// TypeInfo returns info about TL type.
func (i *InputStorePaymentStarsGiveaway) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "inputStorePaymentStarsGiveaway",
		ID:   InputStorePaymentStarsGiveawayTypeID,
	}
	if i == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "OnlyNewSubscribers",
			SchemaName: "only_new_subscribers",
			Null:       !i.Flags.Has(0),
		},
		{
			Name:       "WinnersAreVisible",
			SchemaName: "winners_are_visible",
			Null:       !i.Flags.Has(3),
		},
		{
			Name:       "Stars",
			SchemaName: "stars",
		},
		{
			Name:       "BoostPeer",
			SchemaName: "boost_peer",
		},
		{
			Name:       "AdditionalPeers",
			SchemaName: "additional_peers",
			Null:       !i.Flags.Has(1),
		},
		{
			Name:       "CountriesISO2",
			SchemaName: "countries_iso2",
			Null:       !i.Flags.Has(2),
		},
		{
			Name:       "PrizeDescription",
			SchemaName: "prize_description",
			Null:       !i.Flags.Has(4),
		},
		{
			Name:       "RandomID",
			SchemaName: "random_id",
		},
		{
			Name:       "UntilDate",
			SchemaName: "until_date",
		},
		{
			Name:       "Currency",
			SchemaName: "currency",
		},
		{
			Name:       "Amount",
			SchemaName: "amount",
		},
		{
			Name:       "Users",
			SchemaName: "users",
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (i *InputStorePaymentStarsGiveaway) SetFlags() {
	if !(i.OnlyNewSubscribers == false) {
		i.Flags.Set(0)
	}
	if !(i.WinnersAreVisible == false) {
		i.Flags.Set(3)
	}
	if !(i.AdditionalPeers == nil) {
		i.Flags.Set(1)
	}
	if !(i.CountriesISO2 == nil) {
		i.Flags.Set(2)
	}
	if !(i.PrizeDescription == "") {
		i.Flags.Set(4)
	}
}

// Encode implements bin.Encoder.
func (i *InputStorePaymentStarsGiveaway) Encode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentStarsGiveaway#751f08fa as nil")
	}
	b.PutID(InputStorePaymentStarsGiveawayTypeID)
	return i.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (i *InputStorePaymentStarsGiveaway) EncodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentStarsGiveaway#751f08fa as nil")
	}
	i.SetFlags()
	if err := i.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentStarsGiveaway#751f08fa: field flags: %w", err)
	}
	b.PutLong(i.Stars)
	if i.BoostPeer == nil {
		return fmt.Errorf("unable to encode inputStorePaymentStarsGiveaway#751f08fa: field boost_peer is nil")
	}
	if err := i.BoostPeer.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentStarsGiveaway#751f08fa: field boost_peer: %w", err)
	}
	if i.Flags.Has(1) {
		b.PutVectorHeader(len(i.AdditionalPeers))
		for idx, v := range i.AdditionalPeers {
			if v == nil {
				return fmt.Errorf("unable to encode inputStorePaymentStarsGiveaway#751f08fa: field additional_peers element with index %d is nil", idx)
			}
			if err := v.Encode(b); err != nil {
				return fmt.Errorf("unable to encode inputStorePaymentStarsGiveaway#751f08fa: field additional_peers element with index %d: %w", idx, err)
			}
		}
	}
	if i.Flags.Has(2) {
		b.PutVectorHeader(len(i.CountriesISO2))
		for _, v := range i.CountriesISO2 {
			b.PutString(v)
		}
	}
	if i.Flags.Has(4) {
		b.PutString(i.PrizeDescription)
	}
	b.PutLong(i.RandomID)
	b.PutInt(i.UntilDate)
	b.PutString(i.Currency)
	b.PutLong(i.Amount)
	b.PutInt(i.Users)
	return nil
}

// Decode implements bin.Decoder.
func (i *InputStorePaymentStarsGiveaway) Decode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentStarsGiveaway#751f08fa to nil")
	}
	if err := b.ConsumeID(InputStorePaymentStarsGiveawayTypeID); err != nil {
		return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: %w", err)
	}
	return i.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (i *InputStorePaymentStarsGiveaway) DecodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentStarsGiveaway#751f08fa to nil")
	}
	{
		if err := i.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field flags: %w", err)
		}
	}
	i.OnlyNewSubscribers = i.Flags.Has(0)
	i.WinnersAreVisible = i.Flags.Has(3)
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field stars: %w", err)
		}
		i.Stars = value
	}
	{
		value, err := DecodeInputPeer(b)
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field boost_peer: %w", err)
		}
		i.BoostPeer = value
	}
	if i.Flags.Has(1) {
		headerLen, err := b.VectorHeader()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field additional_peers: %w", err)
		}

		if headerLen > 0 {
			i.AdditionalPeers = make([]InputPeerClass, 0, headerLen%bin.PreallocateLimit)
		}
		for idx := 0; idx < headerLen; idx++ {
			value, err := DecodeInputPeer(b)
			if err != nil {
				return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field additional_peers: %w", err)
			}
			i.AdditionalPeers = append(i.AdditionalPeers, value)
		}
	}
	if i.Flags.Has(2) {
		headerLen, err := b.VectorHeader()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field countries_iso2: %w", err)
		}

		if headerLen > 0 {
			i.CountriesISO2 = make([]string, 0, headerLen%bin.PreallocateLimit)
		}
		for idx := 0; idx < headerLen; idx++ {
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field countries_iso2: %w", err)
			}
			i.CountriesISO2 = append(i.CountriesISO2, value)
		}
	}
	if i.Flags.Has(4) {
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field prize_description: %w", err)
		}
		i.PrizeDescription = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field random_id: %w", err)
		}
		i.RandomID = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field until_date: %w", err)
		}
		i.UntilDate = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field currency: %w", err)
		}
		i.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field amount: %w", err)
		}
		i.Amount = value
	}
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentStarsGiveaway#751f08fa: field users: %w", err)
		}
		i.Users = value
	}
	return nil
}

// SetOnlyNewSubscribers sets value of OnlyNewSubscribers conditional field.
func (i *InputStorePaymentStarsGiveaway) SetOnlyNewSubscribers(value bool) {
	if value {
		i.Flags.Set(0)
		i.OnlyNewSubscribers = true
	} else {
		i.Flags.Unset(0)
		i.OnlyNewSubscribers = false
	}
}

// GetOnlyNewSubscribers returns value of OnlyNewSubscribers conditional field.
func (i *InputStorePaymentStarsGiveaway) GetOnlyNewSubscribers() (value bool) {
	if i == nil {
		return
	}
	return i.Flags.Has(0)
}

// SetWinnersAreVisible sets value of WinnersAreVisible conditional field.
func (i *InputStorePaymentStarsGiveaway) SetWinnersAreVisible(value bool) {
	if value {
		i.Flags.Set(3)
		i.WinnersAreVisible = true
	} else {
		i.Flags.Unset(3)
		i.WinnersAreVisible = false
	}
}

// GetWinnersAreVisible returns value of WinnersAreVisible conditional field.
func (i *InputStorePaymentStarsGiveaway) GetWinnersAreVisible() (value bool) {
	if i == nil {
		return
	}
	return i.Flags.Has(3)
}

// GetStars returns value of Stars field.
func (i *InputStorePaymentStarsGiveaway) GetStars() (value int64) {
	if i == nil {
		return
	}
	return i.Stars
}

// GetBoostPeer returns value of BoostPeer field.
func (i *InputStorePaymentStarsGiveaway) GetBoostPeer() (value InputPeerClass) {
	if i == nil {
		return
	}
	return i.BoostPeer
}

// SetAdditionalPeers sets value of AdditionalPeers conditional field.
func (i *InputStorePaymentStarsGiveaway) SetAdditionalPeers(value []InputPeerClass) {
	i.Flags.Set(1)
	i.AdditionalPeers = value
}

// GetAdditionalPeers returns value of AdditionalPeers conditional field and
// boolean which is true if field was set.
func (i *InputStorePaymentStarsGiveaway) GetAdditionalPeers() (value []InputPeerClass, ok bool) {
	if i == nil {
		return
	}
	if !i.Flags.Has(1) {
		return value, false
	}
	return i.AdditionalPeers, true
}

// SetCountriesISO2 sets value of CountriesISO2 conditional field.
func (i *InputStorePaymentStarsGiveaway) SetCountriesISO2(value []string) {
	i.Flags.Set(2)
	i.CountriesISO2 = value
}

// GetCountriesISO2 returns value of CountriesISO2 conditional field and
// boolean which is true if field was set.
func (i *InputStorePaymentStarsGiveaway) GetCountriesISO2() (value []string, ok bool) {
	if i == nil {
		return
	}
	if !i.Flags.Has(2) {
		return value, false
	}
	return i.CountriesISO2, true
}

// SetPrizeDescription sets value of PrizeDescription conditional field.
func (i *InputStorePaymentStarsGiveaway) SetPrizeDescription(value string) {
	i.Flags.Set(4)
	i.PrizeDescription = value
}

// GetPrizeDescription returns value of PrizeDescription conditional field and
// boolean which is true if field was set.
func (i *InputStorePaymentStarsGiveaway) GetPrizeDescription() (value string, ok bool) {
	if i == nil {
		return
	}
	if !i.Flags.Has(4) {
		return value, false
	}
	return i.PrizeDescription, true
}

// GetRandomID returns value of RandomID field.
func (i *InputStorePaymentStarsGiveaway) GetRandomID() (value int64) {
	if i == nil {
		return
	}
	return i.RandomID
}

// GetUntilDate returns value of UntilDate field.
func (i *InputStorePaymentStarsGiveaway) GetUntilDate() (value int) {
	if i == nil {
		return
	}
	return i.UntilDate
}

// GetCurrency returns value of Currency field.
func (i *InputStorePaymentStarsGiveaway) GetCurrency() (value string) {
	if i == nil {
		return
	}
	return i.Currency
}

// GetAmount returns value of Amount field.
func (i *InputStorePaymentStarsGiveaway) GetAmount() (value int64) {
	if i == nil {
		return
	}
	return i.Amount
}

// GetUsers returns value of Users field.
func (i *InputStorePaymentStarsGiveaway) GetUsers() (value int) {
	if i == nil {
		return
	}
	return i.Users
}

// MapAdditionalPeers returns field AdditionalPeers wrapped in InputPeerClassArray helper.
func (i *InputStorePaymentStarsGiveaway) MapAdditionalPeers() (value InputPeerClassArray, ok bool) {
	if !i.Flags.Has(1) {
		return value, false
	}
	return InputPeerClassArray(i.AdditionalPeers), true
}

// InputStorePaymentAuthCode represents TL type `inputStorePaymentAuthCode#9bb2636d`.
// Indicates payment for a login code.
//
// See https://core.telegram.org/constructor/inputStorePaymentAuthCode for reference.
type InputStorePaymentAuthCode struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Set this flag to restore a previously made purchase.
	Restore bool
	// Phone number.
	PhoneNumber string
	// phone_code_hash returned by auth.sendCode¹.
	//
	// Links:
	//  1) https://core.telegram.org/method/auth.sendCode
	PhoneCodeHash string
	// Three-letter ISO 4217 currency¹ code
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments#supported-currencies
	Currency string
	// Price of the product in the smallest units of the currency (integer, not float/double)
	// For example, for a price of US$ 1.45 pass amount = 145. See the exp parameter in
	// currencies.json¹, it shows the number of digits past the decimal point for each
	// currency (2 for the majority of currencies).
	//
	// Links:
	//  1) https://core.telegram.org/bots/payments/currencies.json
	Amount int64
}

// InputStorePaymentAuthCodeTypeID is TL type id of InputStorePaymentAuthCode.
const InputStorePaymentAuthCodeTypeID = 0x9bb2636d

// construct implements constructor of InputStorePaymentPurposeClass.
func (i InputStorePaymentAuthCode) construct() InputStorePaymentPurposeClass { return &i }

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

	_ InputStorePaymentPurposeClass = &InputStorePaymentAuthCode{}
)

func (i *InputStorePaymentAuthCode) Zero() bool {
	if i == nil {
		return true
	}
	if !(i.Flags.Zero()) {
		return false
	}
	if !(i.Restore == false) {
		return false
	}
	if !(i.PhoneNumber == "") {
		return false
	}
	if !(i.PhoneCodeHash == "") {
		return false
	}
	if !(i.Currency == "") {
		return false
	}
	if !(i.Amount == 0) {
		return false
	}

	return true
}

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

// FillFrom fills InputStorePaymentAuthCode from given interface.
func (i *InputStorePaymentAuthCode) FillFrom(from interface {
	GetRestore() (value bool)
	GetPhoneNumber() (value string)
	GetPhoneCodeHash() (value string)
	GetCurrency() (value string)
	GetAmount() (value int64)
}) {
	i.Restore = from.GetRestore()
	i.PhoneNumber = from.GetPhoneNumber()
	i.PhoneCodeHash = from.GetPhoneCodeHash()
	i.Currency = from.GetCurrency()
	i.Amount = from.GetAmount()
}

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

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

// TypeInfo returns info about TL type.
func (i *InputStorePaymentAuthCode) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "inputStorePaymentAuthCode",
		ID:   InputStorePaymentAuthCodeTypeID,
	}
	if i == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Restore",
			SchemaName: "restore",
			Null:       !i.Flags.Has(0),
		},
		{
			Name:       "PhoneNumber",
			SchemaName: "phone_number",
		},
		{
			Name:       "PhoneCodeHash",
			SchemaName: "phone_code_hash",
		},
		{
			Name:       "Currency",
			SchemaName: "currency",
		},
		{
			Name:       "Amount",
			SchemaName: "amount",
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (i *InputStorePaymentAuthCode) SetFlags() {
	if !(i.Restore == false) {
		i.Flags.Set(0)
	}
}

// Encode implements bin.Encoder.
func (i *InputStorePaymentAuthCode) Encode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentAuthCode#9bb2636d as nil")
	}
	b.PutID(InputStorePaymentAuthCodeTypeID)
	return i.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (i *InputStorePaymentAuthCode) EncodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't encode inputStorePaymentAuthCode#9bb2636d as nil")
	}
	i.SetFlags()
	if err := i.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode inputStorePaymentAuthCode#9bb2636d: field flags: %w", err)
	}
	b.PutString(i.PhoneNumber)
	b.PutString(i.PhoneCodeHash)
	b.PutString(i.Currency)
	b.PutLong(i.Amount)
	return nil
}

// Decode implements bin.Decoder.
func (i *InputStorePaymentAuthCode) Decode(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentAuthCode#9bb2636d to nil")
	}
	if err := b.ConsumeID(InputStorePaymentAuthCodeTypeID); err != nil {
		return fmt.Errorf("unable to decode inputStorePaymentAuthCode#9bb2636d: %w", err)
	}
	return i.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (i *InputStorePaymentAuthCode) DecodeBare(b *bin.Buffer) error {
	if i == nil {
		return fmt.Errorf("can't decode inputStorePaymentAuthCode#9bb2636d to nil")
	}
	{
		if err := i.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentAuthCode#9bb2636d: field flags: %w", err)
		}
	}
	i.Restore = i.Flags.Has(0)
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentAuthCode#9bb2636d: field phone_number: %w", err)
		}
		i.PhoneNumber = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentAuthCode#9bb2636d: field phone_code_hash: %w", err)
		}
		i.PhoneCodeHash = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentAuthCode#9bb2636d: field currency: %w", err)
		}
		i.Currency = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode inputStorePaymentAuthCode#9bb2636d: field amount: %w", err)
		}
		i.Amount = value
	}
	return nil
}

// SetRestore sets value of Restore conditional field.
func (i *InputStorePaymentAuthCode) SetRestore(value bool) {
	if value {
		i.Flags.Set(0)
		i.Restore = true
	} else {
		i.Flags.Unset(0)
		i.Restore = false
	}
}

// GetRestore returns value of Restore conditional field.
func (i *InputStorePaymentAuthCode) GetRestore() (value bool) {
	if i == nil {
		return
	}
	return i.Flags.Has(0)
}

// GetPhoneNumber returns value of PhoneNumber field.
func (i *InputStorePaymentAuthCode) GetPhoneNumber() (value string) {
	if i == nil {
		return
	}
	return i.PhoneNumber
}

// GetPhoneCodeHash returns value of PhoneCodeHash field.
func (i *InputStorePaymentAuthCode) GetPhoneCodeHash() (value string) {
	if i == nil {
		return
	}
	return i.PhoneCodeHash
}

// GetCurrency returns value of Currency field.
func (i *InputStorePaymentAuthCode) GetCurrency() (value string) {
	if i == nil {
		return
	}
	return i.Currency
}

// GetAmount returns value of Amount field.
func (i *InputStorePaymentAuthCode) GetAmount() (value int64) {
	if i == nil {
		return
	}
	return i.Amount
}

// InputStorePaymentPurposeClassName is schema name of InputStorePaymentPurposeClass.
const InputStorePaymentPurposeClassName = "InputStorePaymentPurpose"

// InputStorePaymentPurposeClass represents InputStorePaymentPurpose generic type.
//
// See https://core.telegram.org/type/InputStorePaymentPurpose for reference.
//
// Example:
//
//	g, err := tg.DecodeInputStorePaymentPurpose(buf)
//	if err != nil {
//	    panic(err)
//	}
//	switch v := g.(type) {
//	case *tg.InputStorePaymentPremiumSubscription: // inputStorePaymentPremiumSubscription#a6751e66
//	case *tg.InputStorePaymentGiftPremium: // inputStorePaymentGiftPremium#616f7fe8
//	case *tg.InputStorePaymentPremiumGiftCode: // inputStorePaymentPremiumGiftCode#fb790393
//	case *tg.InputStorePaymentPremiumGiveaway: // inputStorePaymentPremiumGiveaway#160544ca
//	case *tg.InputStorePaymentStarsTopup: // inputStorePaymentStarsTopup#f9a2a6cb
//	case *tg.InputStorePaymentStarsGift: // inputStorePaymentStarsGift#1d741ef7
//	case *tg.InputStorePaymentStarsGiveaway: // inputStorePaymentStarsGiveaway#751f08fa
//	case *tg.InputStorePaymentAuthCode: // inputStorePaymentAuthCode#9bb2636d
//	default: panic(v)
//	}
type InputStorePaymentPurposeClass interface {
	bin.Encoder
	bin.Decoder
	bin.BareEncoder
	bin.BareDecoder
	construct() InputStorePaymentPurposeClass

	// 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
}

// DecodeInputStorePaymentPurpose implements binary de-serialization for InputStorePaymentPurposeClass.
func DecodeInputStorePaymentPurpose(buf *bin.Buffer) (InputStorePaymentPurposeClass, error) {
	id, err := buf.PeekID()
	if err != nil {
		return nil, err
	}
	switch id {
	case InputStorePaymentPremiumSubscriptionTypeID:
		// Decoding inputStorePaymentPremiumSubscription#a6751e66.
		v := InputStorePaymentPremiumSubscription{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode InputStorePaymentPurposeClass: %w", err)
		}
		return &v, nil
	case InputStorePaymentGiftPremiumTypeID:
		// Decoding inputStorePaymentGiftPremium#616f7fe8.
		v := InputStorePaymentGiftPremium{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode InputStorePaymentPurposeClass: %w", err)
		}
		return &v, nil
	case InputStorePaymentPremiumGiftCodeTypeID:
		// Decoding inputStorePaymentPremiumGiftCode#fb790393.
		v := InputStorePaymentPremiumGiftCode{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode InputStorePaymentPurposeClass: %w", err)
		}
		return &v, nil
	case InputStorePaymentPremiumGiveawayTypeID:
		// Decoding inputStorePaymentPremiumGiveaway#160544ca.
		v := InputStorePaymentPremiumGiveaway{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode InputStorePaymentPurposeClass: %w", err)
		}
		return &v, nil
	case InputStorePaymentStarsTopupTypeID:
		// Decoding inputStorePaymentStarsTopup#f9a2a6cb.
		v := InputStorePaymentStarsTopup{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode InputStorePaymentPurposeClass: %w", err)
		}
		return &v, nil
	case InputStorePaymentStarsGiftTypeID:
		// Decoding inputStorePaymentStarsGift#1d741ef7.
		v := InputStorePaymentStarsGift{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode InputStorePaymentPurposeClass: %w", err)
		}
		return &v, nil
	case InputStorePaymentStarsGiveawayTypeID:
		// Decoding inputStorePaymentStarsGiveaway#751f08fa.
		v := InputStorePaymentStarsGiveaway{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode InputStorePaymentPurposeClass: %w", err)
		}
		return &v, nil
	case InputStorePaymentAuthCodeTypeID:
		// Decoding inputStorePaymentAuthCode#9bb2636d.
		v := InputStorePaymentAuthCode{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode InputStorePaymentPurposeClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode InputStorePaymentPurposeClass: %w", bin.NewUnexpectedID(id))
	}
}

// InputStorePaymentPurpose boxes the InputStorePaymentPurposeClass providing a helper.
type InputStorePaymentPurposeBox struct {
	InputStorePaymentPurpose InputStorePaymentPurposeClass
}

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

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