1// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
3package pagination
4
5import (
6 "net/http"
7 "reflect"
8
9 "github.com/openai/openai-go/internal/apijson"
10 "github.com/openai/openai-go/internal/requestconfig"
11 "github.com/openai/openai-go/option"
12 "github.com/openai/openai-go/packages/param"
13 "github.com/openai/openai-go/packages/respjson"
14)
15
16// aliased to make [param.APIUnion] private when embedding
17type paramUnion = param.APIUnion
18
19// aliased to make [param.APIObject] private when embedding
20type paramObj = param.APIObject
21
22type Page[T any] struct {
23 Data []T `json:"data"`
24 Object string `json:"object,required"`
25 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
26 JSON struct {
27 Data respjson.Field
28 Object respjson.Field
29 ExtraFields map[string]respjson.Field
30 raw string
31 } `json:"-"`
32 cfg *requestconfig.RequestConfig
33 res *http.Response
34}
35
36// Returns the unmodified JSON received from the API
37func (r Page[T]) RawJSON() string { return r.JSON.raw }
38func (r *Page[T]) UnmarshalJSON(data []byte) error {
39 return apijson.UnmarshalRoot(data, r)
40}
41
42// GetNextPage returns the next page as defined by this pagination style. When
43// there is no next page, this function will return a 'nil' for the page value, but
44// will not return an error
45func (r *Page[T]) GetNextPage() (res *Page[T], err error) {
46 if len(r.Data) == 0 {
47 return nil, nil
48 }
49 // This page represents a response that isn't actually paginated at the API level
50 // so there will never be a next page.
51 cfg := (*requestconfig.RequestConfig)(nil)
52 if cfg == nil {
53 return nil, nil
54 }
55 var raw *http.Response
56 cfg.ResponseInto = &raw
57 cfg.ResponseBodyInto = &res
58 err = cfg.Execute()
59 if err != nil {
60 return nil, err
61 }
62 res.SetPageConfig(cfg, raw)
63 return res, nil
64}
65
66func (r *Page[T]) SetPageConfig(cfg *requestconfig.RequestConfig, res *http.Response) {
67 if r == nil {
68 r = &Page[T]{}
69 }
70 r.cfg = cfg
71 r.res = res
72}
73
74type PageAutoPager[T any] struct {
75 page *Page[T]
76 cur T
77 idx int
78 run int
79 err error
80 paramObj
81}
82
83func NewPageAutoPager[T any](page *Page[T], err error) *PageAutoPager[T] {
84 return &PageAutoPager[T]{
85 page: page,
86 err: err,
87 }
88}
89
90func (r *PageAutoPager[T]) Next() bool {
91 if r.page == nil || len(r.page.Data) == 0 {
92 return false
93 }
94 if r.idx >= len(r.page.Data) {
95 r.idx = 0
96 r.page, r.err = r.page.GetNextPage()
97 if r.err != nil || r.page == nil || len(r.page.Data) == 0 {
98 return false
99 }
100 }
101 r.cur = r.page.Data[r.idx]
102 r.run += 1
103 r.idx += 1
104 return true
105}
106
107func (r *PageAutoPager[T]) Current() T {
108 return r.cur
109}
110
111func (r *PageAutoPager[T]) Err() error {
112 return r.err
113}
114
115func (r *PageAutoPager[T]) Index() int {
116 return r.run
117}
118
119type CursorPage[T any] struct {
120 Data []T `json:"data"`
121 HasMore bool `json:"has_more"`
122 // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
123 JSON struct {
124 Data respjson.Field
125 HasMore respjson.Field
126 ExtraFields map[string]respjson.Field
127 raw string
128 } `json:"-"`
129 cfg *requestconfig.RequestConfig
130 res *http.Response
131}
132
133// Returns the unmodified JSON received from the API
134func (r CursorPage[T]) RawJSON() string { return r.JSON.raw }
135func (r *CursorPage[T]) UnmarshalJSON(data []byte) error {
136 return apijson.UnmarshalRoot(data, r)
137}
138
139// GetNextPage returns the next page as defined by this pagination style. When
140// there is no next page, this function will return a 'nil' for the page value, but
141// will not return an error
142func (r *CursorPage[T]) GetNextPage() (res *CursorPage[T], err error) {
143 if len(r.Data) == 0 {
144 return nil, nil
145 }
146
147 if r.JSON.HasMore.Valid() && r.HasMore == false {
148 return nil, nil
149 }
150 items := r.Data
151 if items == nil || len(items) == 0 {
152 return nil, nil
153 }
154 cfg := r.cfg.Clone(r.cfg.Context)
155 value := reflect.ValueOf(items[len(items)-1])
156 field := value.FieldByName("ID")
157 err = cfg.Apply(option.WithQuery("after", field.Interface().(string)))
158 if err != nil {
159 return nil, err
160 }
161 var raw *http.Response
162 cfg.ResponseInto = &raw
163 cfg.ResponseBodyInto = &res
164 err = cfg.Execute()
165 if err != nil {
166 return nil, err
167 }
168 res.SetPageConfig(cfg, raw)
169 return res, nil
170}
171
172func (r *CursorPage[T]) SetPageConfig(cfg *requestconfig.RequestConfig, res *http.Response) {
173 if r == nil {
174 r = &CursorPage[T]{}
175 }
176 r.cfg = cfg
177 r.res = res
178}
179
180type CursorPageAutoPager[T any] struct {
181 page *CursorPage[T]
182 cur T
183 idx int
184 run int
185 err error
186 paramObj
187}
188
189func NewCursorPageAutoPager[T any](page *CursorPage[T], err error) *CursorPageAutoPager[T] {
190 return &CursorPageAutoPager[T]{
191 page: page,
192 err: err,
193 }
194}
195
196func (r *CursorPageAutoPager[T]) Next() bool {
197 if r.page == nil || len(r.page.Data) == 0 {
198 return false
199 }
200 if r.idx >= len(r.page.Data) {
201 r.idx = 0
202 r.page, r.err = r.page.GetNextPage()
203 if r.err != nil || r.page == nil || len(r.page.Data) == 0 {
204 return false
205 }
206 }
207 r.cur = r.page.Data[r.idx]
208 r.run += 1
209 r.idx += 1
210 return true
211}
212
213func (r *CursorPageAutoPager[T]) Current() T {
214 return r.cur
215}
216
217func (r *CursorPageAutoPager[T]) Err() error {
218 return r.err
219}
220
221func (r *CursorPageAutoPager[T]) Index() int {
222 return r.run
223}