// Code generated by go generate cmd/definitions; DO NOT EDIT.
package types

import (
	"context"
	"errors"
	"fmt"
)

type Continuable interface {
	ContinuationToken() string
}

// NextBlockFunc is the func used in iterator.
//
// Notes
// - ErrDone should be return while there are no items any more.
// - Input Block slice should be set every time.
type NextBlockFunc func(ctx context.Context, page *BlockPage) error
type BlockPage struct {
	Status Continuable
	Data   []*Block
}
type BlockIterator struct {
	ctx  context.Context
	next NextBlockFunc

	index int
	done  bool

	o BlockPage
}

func NewBlockIterator(ctx context.Context, next NextBlockFunc, status Continuable) *BlockIterator {
	return &BlockIterator{ctx: ctx, next: next, o: BlockPage{Status: status}}
}
func (it *BlockIterator) ContinuationToken() string {
	return it.o.Status.ContinuationToken()
}
func (it *BlockIterator) Next() (object *Block, err error) {
	// Consume Data via index.
	// Consume Data via index.
	if it.index < len(it.o.Data) {
		it.index++
		return it.o.Data[it.index-1], nil
	}
	// Return IterateDone if iterator is already done.
	if it.done {
		return nil, IterateDone
	}

	// Reset buf before call next.
	it.o.Data = it.o.Data[:0]

	err = it.next(it.ctx, &it.o)
	if err != nil && !errors.Is(err, IterateDone) {
		return nil, fmt.Errorf("iterator next failed: %w", err)
	}
	// Make iterator to done so that we will not fetch from upstream anymore.
	if err != nil {
		it.done = true
	}
	// Return IterateDone directly if we don't have any data.
	if len(it.o.Data) == 0 {
		return nil, IterateDone
	}
	// Return the first object.
	it.index = 1
	return it.o.Data[0], nil
}

// NextObjectFunc is the func used in iterator.
//
// Notes
// - ErrDone should be return while there are no items any more.
// - Input Object slice should be set every time.
type NextObjectFunc func(ctx context.Context, page *ObjectPage) error
type ObjectPage struct {
	Status Continuable
	Data   []*Object
}
type ObjectIterator struct {
	ctx  context.Context
	next NextObjectFunc

	index int
	done  bool

	o ObjectPage
}

func NewObjectIterator(ctx context.Context, next NextObjectFunc, status Continuable) *ObjectIterator {
	return &ObjectIterator{ctx: ctx, next: next, o: ObjectPage{Status: status}}
}
func (it *ObjectIterator) ContinuationToken() string {
	return it.o.Status.ContinuationToken()
}
func (it *ObjectIterator) Next() (object *Object, err error) {
	// Consume Data via index.
	// Consume Data via index.
	if it.index < len(it.o.Data) {
		it.index++
		return it.o.Data[it.index-1], nil
	}
	// Return IterateDone if iterator is already done.
	if it.done {
		return nil, IterateDone
	}

	// Reset buf before call next.
	it.o.Data = it.o.Data[:0]

	err = it.next(it.ctx, &it.o)
	if err != nil && !errors.Is(err, IterateDone) {
		return nil, fmt.Errorf("iterator next failed: %w", err)
	}
	// Make iterator to done so that we will not fetch from upstream anymore.
	if err != nil {
		it.done = true
	}
	// Return IterateDone directly if we don't have any data.
	if len(it.o.Data) == 0 {
		return nil, IterateDone
	}
	// Return the first object.
	it.index = 1
	return it.o.Data[0], nil
}

// NextPartFunc is the func used in iterator.
//
// Notes
// - ErrDone should be return while there are no items any more.
// - Input Part slice should be set every time.
type NextPartFunc func(ctx context.Context, page *PartPage) error
type PartPage struct {
	Status Continuable
	Data   []*Part
}
type PartIterator struct {
	ctx  context.Context
	next NextPartFunc

	index int
	done  bool

	o PartPage
}

func NewPartIterator(ctx context.Context, next NextPartFunc, status Continuable) *PartIterator {
	return &PartIterator{ctx: ctx, next: next, o: PartPage{Status: status}}
}
func (it *PartIterator) ContinuationToken() string {
	return it.o.Status.ContinuationToken()
}
func (it *PartIterator) Next() (object *Part, err error) {
	// Consume Data via index.
	// Consume Data via index.
	if it.index < len(it.o.Data) {
		it.index++
		return it.o.Data[it.index-1], nil
	}
	// Return IterateDone if iterator is already done.
	if it.done {
		return nil, IterateDone
	}

	// Reset buf before call next.
	it.o.Data = it.o.Data[:0]

	err = it.next(it.ctx, &it.o)
	if err != nil && !errors.Is(err, IterateDone) {
		return nil, fmt.Errorf("iterator next failed: %w", err)
	}
	// Make iterator to done so that we will not fetch from upstream anymore.
	if err != nil {
		it.done = true
	}
	// Return IterateDone directly if we don't have any data.
	if len(it.o.Data) == 0 {
		return nil, IterateDone
	}
	// Return the first object.
	it.index = 1
	return it.o.Data[0], nil
}

// NextStoragerFunc is the func used in iterator.
//
// Notes
// - ErrDone should be return while there are no items any more.
// - Input Storager slice should be set every time.
type NextStoragerFunc func(ctx context.Context, page *StoragerPage) error
type StoragerPage struct {
	Status Continuable
	Data   []Storager
}
type StoragerIterator struct {
	ctx  context.Context
	next NextStoragerFunc

	index int
	done  bool

	o StoragerPage
}

func NewStoragerIterator(ctx context.Context, next NextStoragerFunc, status Continuable) *StoragerIterator {
	return &StoragerIterator{ctx: ctx, next: next, o: StoragerPage{Status: status}}
}
func (it *StoragerIterator) ContinuationToken() string {
	return it.o.Status.ContinuationToken()
}
func (it *StoragerIterator) Next() (object Storager, err error) {
	// Consume Data via index.
	// Consume Data via index.
	if it.index < len(it.o.Data) {
		it.index++
		return it.o.Data[it.index-1], nil
	}
	// Return IterateDone if iterator is already done.
	if it.done {
		return nil, IterateDone
	}

	// Reset buf before call next.
	it.o.Data = it.o.Data[:0]

	err = it.next(it.ctx, &it.o)
	if err != nil && !errors.Is(err, IterateDone) {
		return nil, fmt.Errorf("iterator next failed: %w", err)
	}
	// Make iterator to done so that we will not fetch from upstream anymore.
	if err != nil {
		it.done = true
	}
	// Return IterateDone directly if we don't have any data.
	if len(it.o.Data) == 0 {
		return nil, IterateDone
	}
	// Return the first object.
	it.index = 1
	return it.o.Data[0], nil
}
