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