bookstack-api/iterator.go

50 lines
1.1 KiB
Go
Raw Permalink Normal View History

package bookstack
import (
"context"
"encoding/json"
"fmt"
"iter"
)
const defaultPageSize = 100
// listAllResponse is used internally to get both data and total from paginated endpoints.
type listAllResponse struct {
Data json.RawMessage `json:"data"`
Total int `json:"total"`
}
// listAll returns an iterator that paginates through all results for the given path.
func listAll[T any](ctx context.Context, c *Client, path string) iter.Seq2[T, error] {
return func(yield func(T, error) bool) {
offset := 0
for {
var resp listAllResponse
url := fmt.Sprintf("%s?count=%d&offset=%d", path, defaultPageSize, offset)
if err := c.do(ctx, "GET", url, nil, &resp); err != nil {
var zero T
yield(zero, err)
return
}
var items []T
if err := json.Unmarshal(resp.Data, &items); err != nil {
var zero T
yield(zero, fmt.Errorf("unmarshaling page data: %w", err))
return
}
for _, item := range items {
if !yield(item, nil) {
return
}
}
offset += len(items)
if offset >= resp.Total || len(items) == 0 {
return
}
}
}
}