From fb8396518921eb5ab5bc413674f56f76f92d2daa Mon Sep 17 00:00:00 2001 From: Leo Antunes Date: Wed, 7 Feb 2024 12:07:48 +0100 Subject: [PATCH] feat: add experimental iterator --- iterator.go | 41 +++++++++++++++++++++++++++++++++++++++++ pagination.go | 20 ++++++++++++-------- 2 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 iterator.go diff --git a/iterator.go b/iterator.go new file mode 100644 index 000000000..914864767 --- /dev/null +++ b/iterator.go @@ -0,0 +1,41 @@ +//go:build go1.22 && goexperiment.rangefunc +// +build go1.22,goexperiment.rangefunc + +package gitlab + +import ( + "iter" +) + +// PageIterator is an EXPERIMENTAL iterator as defined in the "rangefunc" experiment for go 1.22. +// See https://go.dev/wiki/RangefuncExperiment for more details. +// +// It can be used as: +// +// for user, err := range gitlab.PageIterator(gl.Users.List, nil) { +// if err != nil { +// // handle error +// } +// // process individual user +// } +func PageIterator[O, T any](f Paginatable[O, T], opt *O, optFunc ...RequestOptionFunc) iter.Seq2[*T, error] { + return func(yield func(*T, error) bool) { + nextLink := "" + for { + page, resp, err := f(opt, append(optFunc, WithKeysetPaginationParameters(nextLink))...) + if err != nil { + yield(nil, err) + return + } + for _, p := range page { + if !yield(p, nil) { + return + } + } + if resp.NextLink == "" { + break + } + nextLink = resp.NextLink + } + } +} diff --git a/pagination.go b/pagination.go index 0bfb0f561..910afc559 100644 --- a/pagination.go +++ b/pagination.go @@ -6,18 +6,22 @@ package gitlab // // It is also possible to specify additional pagination parameters: // -// mrs, err := gitlab.AllPages(gl.MergeRequests.ListMergeRequests, &gitlab.ListMergeRequestsOptions{ -// ListOptions: gitlab.ListOptions{ -// PerPage: 100, -// Pagination: "keyset", -// OrderBy: "created_at", +// mrs, err := gitlab.AllPages( +// gl.MergeRequests.ListMergeRequests, +// &gitlab.ListMergeRequestsOptions{ +// ListOptions: gitlab.ListOptions{ +// PerPage: 100, +// Pagination: "keyset", +// OrderBy: "created_at", +// }, // }, -// }) -func AllPages[O, T any](f Paginatable[O, T], opt *O) ([]*T, error) { +// gitlab.WithContext(ctx), +// ) +func AllPages[O, T any](f Paginatable[O, T], opt *O, optFunc ...RequestOptionFunc) ([]*T, error) { all := make([]*T, 0) nextLink := "" for { - page, resp, err := f(opt, WithKeysetPaginationParameters(nextLink)) + page, resp, err := f(opt, append(optFunc, WithKeysetPaginationParameters(nextLink))...) if err != nil { return nil, err }