Verified Commit 1cd1e1e5 authored by Florian Forster's avatar Florian Forster
Browse files

feat(request_options): Add boolean return value to `WithNext`.

`WithNext` previously used inline signaling by returning `nil` when no more
pages were available. This required callers to check for nil, which is easy to
overlook and inconsistent with Go conventions.

Add a second boolean return value following the comma-ok idiom used by map
accesses and type assertions. This makes pagination termination explicit and
harder to miss.

Update `Scan2`, `ExampleWithNext`, and all call sites accordingly.
parent 55e59d89
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -99,11 +99,11 @@ func Scan[T any](f func(p PaginationOptionFunc) ([]T, *Response, error)) (iter.S
// Attention: This API is experimental and may be subject to breaking changes to improve the API in the future.
func Scan2[T any](f func(p PaginationOptionFunc) ([]T, *Response, error)) iter.Seq2[T, error] {
	return func(yield func(T, error) bool) {
		var nextOpt PaginationOptionFunc
		var page PaginationOptionFunc

	Pagination:
		for {
			ts, resp, err := f(nextOpt)
			ts, resp, err := f(page)
			if err != nil {
				var t T
				yield(t, err)
@@ -119,11 +119,13 @@ func Scan2[T any](f func(p PaginationOptionFunc) ([]T, *Response, error)) iter.S
			// the f request function was either configured for offset- or keyset-based
			// pagination. We support both here, by checking if the next link is provided (keyset)
			// or not. If both are provided, keyset-based pagination takes precedence.
			nextOpt = WithNext(resp)
			if nextOpt == nil {
			next, ok := WithNext(resp)
			if !ok {
				// no more pages
				break Pagination
			}

			page = next
		}
	}
}
+8 −7
Original line number Diff line number Diff line
@@ -151,21 +151,22 @@ func withGraphQLPaginationParamters(pi PageInfo) RequestOptionFunc {
// If multiple pagination styles are present in the response, keyset/cursor pagination
// is preferred over offset pagination for better performance and consistency.
//
// Returns nil if the response indicates there are no more pages (HasNextPage=false,
// no NextLink, or NextPage=0).
func WithNext(resp *Response) RequestOptionFunc {
// The boolean return value indicates whether more pages are available, similar to
// the comma-ok idiom used for map accesses. When false, the returned
// RequestOptionFunc is nil.
func WithNext(resp *Response) (RequestOptionFunc, bool) {
	switch {
	case resp.PageInfo != nil:
		return withGraphQLPaginationParamters(*resp.PageInfo)
		return withGraphQLPaginationParamters(*resp.PageInfo), resp.PageInfo.HasNextPage

	case resp.NextLink != "":
		return WithKeysetPaginationParameters(resp.NextLink)
		return WithKeysetPaginationParameters(resp.NextLink), true

	case resp.NextPage != 0:
		return WithOffsetPaginationParameters(resp.NextPage)
		return WithOffsetPaginationParameters(resp.NextPage), true

	default:
		return nil
		return nil, false
	}
}

+4 −2
Original line number Diff line number Diff line
@@ -486,10 +486,12 @@ func ExampleWithNext() {
		// Process mrs...
		_ = mrs

		page = WithNext(resp)
		if page == nil {
		next, ok := WithNext(resp)
		if !ok {
			// No more pages, break the loop
			break
		}

		page = next
	}
}