docker-distribution/vendor/github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/pager.go

78 lines
1.9 KiB
Go

//go:build go1.18
// +build go1.18
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package runtime
import (
"context"
"encoding/json"
"errors"
)
// PagingHandler contains the required data for constructing a Pager.
type PagingHandler[T any] struct {
// More returns a boolean indicating if there are more pages to fetch.
// It uses the provided page to make the determination.
More func(T) bool
// Fetcher fetches the first and subsequent pages.
Fetcher func(context.Context, *T) (T, error)
}
// Pager provides operations for iterating over paged responses.
type Pager[T any] struct {
current *T
handler PagingHandler[T]
firstPage bool
}
// NewPager creates an instance of Pager using the specified PagingHandler.
// Pass a non-nil T for firstPage if the first page has already been retrieved.
func NewPager[T any](handler PagingHandler[T]) *Pager[T] {
return &Pager[T]{
handler: handler,
firstPage: true,
}
}
// More returns true if there are more pages to retrieve.
func (p *Pager[T]) More() bool {
if p.current != nil {
return p.handler.More(*p.current)
}
return true
}
// NextPage advances the pager to the next page.
func (p *Pager[T]) NextPage(ctx context.Context) (T, error) {
var resp T
var err error
if p.current != nil {
if p.firstPage {
// we get here if it's an LRO-pager, we already have the first page
p.firstPage = false
return *p.current, nil
} else if !p.handler.More(*p.current) {
return *new(T), errors.New("no more pages")
}
resp, err = p.handler.Fetcher(ctx, p.current)
} else {
// non-LRO case, first page
p.firstPage = false
resp, err = p.handler.Fetcher(ctx, nil)
}
if err != nil {
return *new(T), err
}
p.current = &resp
return *p.current, nil
}
// UnmarshalJSON implements the json.Unmarshaler interface for Pager[T].
func (p *Pager[T]) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, &p.current)
}