// Code generated by @openmeter/typespec-go. DO NOT EDIT. package openmeter import ( "fmt" "iter" "net/url" "strconv" ) const defaultListPageSize = 100 const maxPages = 10_000 // PageParams selects a numbered page. type PageParams struct { Size *int Number *int } // CursorPageParams selects a cursor page. type CursorPageParams struct { Size *int After *string Before *string } type PageMeta struct { Number int `json:"number"` Size int `json:"size"` Total int `json:"total"` } type PaginatedMeta struct { Page PageMeta `json:"page"` } func addPageParams(q url.Values, page *PageParams) { if page == nil { return } if page.Size != nil { setDeepObjectString(q, "page", "size", strconv.Itoa(*page.Size)) } if page.Number != nil { setDeepObjectString(q, "page", "number", strconv.Itoa(*page.Number)) } } func addCursorPageParams(q url.Values, page *CursorPageParams) { if page == nil { return } if page.Size != nil { setDeepObjectString(q, "page", "size", strconv.Itoa(*page.Size)) } if page.After != nil { setDeepObjectString(q, "page", "after", *page.After) } if page.Before != nil { setDeepObjectString(q, "page", "before", *page.Before) } } func paginate[T any](start *PageParams, fetch func(page, size int) ([]T, int, error)) iter.Seq2[T, error] { return func(yield func(T, error) bool) { page, size := 1, defaultListPageSize if start != nil { if start.Number != nil { page = *start.Number } if start.Size != nil { size = *start.Size } } seen := 0 for fetched := 0; fetched < maxPages; fetched++ { data, total, err := fetch(page, size) if err != nil { var zero T yield(zero, err) return } for _, item := range data { if !yield(item, nil) { return } } seen += len(data) if len(data) == 0 || (total > 0 && seen >= total) { return } page++ } var zero T yield(zero, fmt.Errorf("openmeter: pagination did not terminate within %d pages", maxPages)) } } func paginateCursor[T any](start *CursorPageParams, fetch func(after, before *string, size int) ([]T, *string, *string, error)) iter.Seq2[T, error] { return func(yield func(T, error) bool) { size := defaultListPageSize var after, before *string if start != nil { after = start.After before = start.Before if after != nil && before != nil { var zero T yield(zero, fmt.Errorf("openmeter: cursor pagination cannot use both after and before")) return } if start.Size != nil { size = *start.Size } } reverse := before != nil for fetched := 0; fetched < maxPages; fetched++ { data, next, previous, err := fetch(after, before, size) if err != nil { var zero T yield(zero, err) return } for _, item := range data { if !yield(item, nil) { return } } if reverse { if previous == nil || *previous == "" || len(data) == 0 { return } before = previous } else { if next == nil || *next == "" || len(data) == 0 { return } after = next } } var zero T yield(zero, fmt.Errorf("openmeter: cursor pagination did not terminate within %d pages", maxPages)) } }