-
Notifications
You must be signed in to change notification settings - Fork 0
/
pagination.go
128 lines (109 loc) · 3.02 KB
/
pagination.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
package pagination
import (
"net/http"
"github.com/orbcorp/orb-go/internal/apijson"
"github.com/orbcorp/orb-go/internal/requestconfig"
"github.com/orbcorp/orb-go/option"
)
type PagePaginationMetadata struct {
HasMore bool `json:"has_more,required"`
NextCursor string `json:"next_cursor,required,nullable"`
JSON pagePaginationMetadataJSON `json:"-"`
}
// pagePaginationMetadataJSON contains the JSON metadata for the struct
// [PagePaginationMetadata]
type pagePaginationMetadataJSON struct {
HasMore apijson.Field
NextCursor apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
func (r *PagePaginationMetadata) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}
func (r pagePaginationMetadataJSON) RawJSON() string {
return r.raw
}
type Page[T any] struct {
Data []T `json:"data"`
PaginationMetadata PagePaginationMetadata `json:"pagination_metadata,required"`
JSON pageJSON `json:"-"`
cfg *requestconfig.RequestConfig
res *http.Response
}
// pageJSON contains the JSON metadata for the struct [Page[T]]
type pageJSON struct {
Data apijson.Field
PaginationMetadata apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
func (r *Page[T]) UnmarshalJSON(data []byte) (err error) {
return apijson.UnmarshalRoot(data, r)
}
func (r pageJSON) RawJSON() string {
return r.raw
}
// NextPage returns the next page as defined by this pagination style. When there
// is no next page, this function will return a 'nil' for the page value, but will
// not return an error
func (r *Page[T]) GetNextPage() (res *Page[T], err error) {
next := r.PaginationMetadata.NextCursor
if len(next) == 0 {
return nil, nil
}
cfg := r.cfg.Clone(r.cfg.Context)
cfg.Apply(option.WithQuery("cursor", next))
var raw *http.Response
cfg.ResponseInto = &raw
cfg.ResponseBodyInto = &res
err = cfg.Execute()
if err != nil {
return nil, err
}
res.SetPageConfig(cfg, raw)
return res, nil
}
func (r *Page[T]) SetPageConfig(cfg *requestconfig.RequestConfig, res *http.Response) {
r.cfg = cfg
r.res = res
}
type PageAutoPager[T any] struct {
page *Page[T]
cur T
idx int
run int
err error
}
func NewPageAutoPager[T any](page *Page[T], err error) *PageAutoPager[T] {
return &PageAutoPager[T]{
page: page,
err: err,
}
}
func (r *PageAutoPager[T]) Next() bool {
if r.page == nil || len(r.page.Data) == 0 {
return false
}
if r.idx >= len(r.page.Data) {
r.idx = 0
r.page, r.err = r.page.GetNextPage()
if r.err != nil || r.page == nil || len(r.page.Data) == 0 {
return false
}
}
r.cur = r.page.Data[r.idx]
r.run += 1
r.idx += 1
return true
}
func (r *PageAutoPager[T]) Current() T {
return r.cur
}
func (r *PageAutoPager[T]) Err() error {
return r.err
}
func (r *PageAutoPager[T]) Index() int {
return r.run
}