]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
update vendor and go.mod
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / aws / aws-sdk-go / aws / request / request_pagination.go
1 package request
2
3 import (
4 "reflect"
5 "sync/atomic"
6
7 "github.com/aws/aws-sdk-go/aws"
8 "github.com/aws/aws-sdk-go/aws/awsutil"
9 )
10
11 // A Pagination provides paginating of SDK API operations which are paginatable.
12 // Generally you should not use this type directly, but use the "Pages" API
13 // operations method to automatically perform pagination for you. Such as,
14 // "S3.ListObjectsPages", and "S3.ListObjectsPagesWithContext" methods.
15 //
16 // Pagination differs from a Paginator type in that pagination is the type that
17 // does the pagination between API operations, and Paginator defines the
18 // configuration that will be used per page request.
19 //
20 // cont := true
21 // for p.Next() && cont {
22 // data := p.Page().(*s3.ListObjectsOutput)
23 // // process the page's data
24 // }
25 // return p.Err()
26 //
27 // See service client API operation Pages methods for examples how the SDK will
28 // use the Pagination type.
29 type Pagination struct {
30 // Function to return a Request value for each pagination request.
31 // Any configuration or handlers that need to be applied to the request
32 // prior to getting the next page should be done here before the request
33 // returned.
34 //
35 // NewRequest should always be built from the same API operations. It is
36 // undefined if different API operations are returned on subsequent calls.
37 NewRequest func() (*Request, error)
38 // EndPageOnSameToken, when enabled, will allow the paginator to stop on
39 // token that are the same as its previous tokens.
40 EndPageOnSameToken bool
41
42 started bool
43 prevTokens []interface{}
44 nextTokens []interface{}
45
46 err error
47 curPage interface{}
48 }
49
50 // HasNextPage will return true if Pagination is able to determine that the API
51 // operation has additional pages. False will be returned if there are no more
52 // pages remaining.
53 //
54 // Will always return true if Next has not been called yet.
55 func (p *Pagination) HasNextPage() bool {
56 if !p.started {
57 return true
58 }
59
60 hasNextPage := len(p.nextTokens) != 0
61 if p.EndPageOnSameToken {
62 return hasNextPage && !awsutil.DeepEqual(p.nextTokens, p.prevTokens)
63 }
64 return hasNextPage
65 }
66
67 // Err returns the error Pagination encountered when retrieving the next page.
68 func (p *Pagination) Err() error {
69 return p.err
70 }
71
72 // Page returns the current page. Page should only be called after a successful
73 // call to Next. It is undefined what Page will return if Page is called after
74 // Next returns false.
75 func (p *Pagination) Page() interface{} {
76 return p.curPage
77 }
78
79 // Next will attempt to retrieve the next page for the API operation. When a page
80 // is retrieved true will be returned. If the page cannot be retrieved, or there
81 // are no more pages false will be returned.
82 //
83 // Use the Page method to retrieve the current page data. The data will need
84 // to be cast to the API operation's output type.
85 //
86 // Use the Err method to determine if an error occurred if Page returns false.
87 func (p *Pagination) Next() bool {
88 if !p.HasNextPage() {
89 return false
90 }
91
92 req, err := p.NewRequest()
93 if err != nil {
94 p.err = err
95 return false
96 }
97
98 if p.started {
99 for i, intok := range req.Operation.InputTokens {
100 awsutil.SetValueAtPath(req.Params, intok, p.nextTokens[i])
101 }
102 }
103 p.started = true
104
105 err = req.Send()
106 if err != nil {
107 p.err = err
108 return false
109 }
110
111 p.prevTokens = p.nextTokens
112 p.nextTokens = req.nextPageTokens()
113 p.curPage = req.Data
114
115 return true
116 }
117
118 // A Paginator is the configuration data that defines how an API operation
119 // should be paginated. This type is used by the API service models to define
120 // the generated pagination config for service APIs.
121 //
122 // The Pagination type is what provides iterating between pages of an API. It
123 // is only used to store the token metadata the SDK should use for performing
124 // pagination.
125 type Paginator struct {
126 InputTokens []string
127 OutputTokens []string
128 LimitToken string
129 TruncationToken string
130 }
131
132 // nextPageTokens returns the tokens to use when asking for the next page of data.
133 func (r *Request) nextPageTokens() []interface{} {
134 if r.Operation.Paginator == nil {
135 return nil
136 }
137 if r.Operation.TruncationToken != "" {
138 tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken)
139 if len(tr) == 0 {
140 return nil
141 }
142
143 switch v := tr[0].(type) {
144 case *bool:
145 if !aws.BoolValue(v) {
146 return nil
147 }
148 case bool:
149 if !v {
150 return nil
151 }
152 }
153 }
154
155 tokens := []interface{}{}
156 tokenAdded := false
157 for _, outToken := range r.Operation.OutputTokens {
158 vs, _ := awsutil.ValuesAtPath(r.Data, outToken)
159 if len(vs) == 0 {
160 tokens = append(tokens, nil)
161 continue
162 }
163 v := vs[0]
164
165 switch tv := v.(type) {
166 case *string:
167 if len(aws.StringValue(tv)) == 0 {
168 tokens = append(tokens, nil)
169 continue
170 }
171 case string:
172 if len(tv) == 0 {
173 tokens = append(tokens, nil)
174 continue
175 }
176 }
177
178 tokenAdded = true
179 tokens = append(tokens, v)
180 }
181 if !tokenAdded {
182 return nil
183 }
184
185 return tokens
186 }
187
188 // Ensure a deprecated item is only logged once instead of each time its used.
189 func logDeprecatedf(logger aws.Logger, flag *int32, msg string) {
190 if logger == nil {
191 return
192 }
193 if atomic.CompareAndSwapInt32(flag, 0, 1) {
194 logger.Log(msg)
195 }
196 }
197
198 var (
199 logDeprecatedHasNextPage int32
200 logDeprecatedNextPage int32
201 logDeprecatedEachPage int32
202 )
203
204 // HasNextPage returns true if this request has more pages of data available.
205 //
206 // Deprecated Use Pagination type for configurable pagination of API operations
207 func (r *Request) HasNextPage() bool {
208 logDeprecatedf(r.Config.Logger, &logDeprecatedHasNextPage,
209 "Request.HasNextPage deprecated. Use Pagination type for configurable pagination of API operations")
210
211 return len(r.nextPageTokens()) > 0
212 }
213
214 // NextPage returns a new Request that can be executed to return the next
215 // page of result data. Call .Send() on this request to execute it.
216 //
217 // Deprecated Use Pagination type for configurable pagination of API operations
218 func (r *Request) NextPage() *Request {
219 logDeprecatedf(r.Config.Logger, &logDeprecatedNextPage,
220 "Request.NextPage deprecated. Use Pagination type for configurable pagination of API operations")
221
222 tokens := r.nextPageTokens()
223 if len(tokens) == 0 {
224 return nil
225 }
226
227 data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface()
228 nr := New(r.Config, r.ClientInfo, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data)
229 for i, intok := range nr.Operation.InputTokens {
230 awsutil.SetValueAtPath(nr.Params, intok, tokens[i])
231 }
232 return nr
233 }
234
235 // EachPage iterates over each page of a paginated request object. The fn
236 // parameter should be a function with the following sample signature:
237 //
238 // func(page *T, lastPage bool) bool {
239 // return true // return false to stop iterating
240 // }
241 //
242 // Where "T" is the structure type matching the output structure of the given
243 // operation. For example, a request object generated by
244 // DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput
245 // as the structure "T". The lastPage value represents whether the page is
246 // the last page of data or not. The return value of this function should
247 // return true to keep iterating or false to stop.
248 //
249 // Deprecated Use Pagination type for configurable pagination of API operations
250 func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error {
251 logDeprecatedf(r.Config.Logger, &logDeprecatedEachPage,
252 "Request.EachPage deprecated. Use Pagination type for configurable pagination of API operations")
253
254 for page := r; page != nil; page = page.NextPage() {
255 if err := page.Send(); err != nil {
256 return err
257 }
258 if getNextPage := fn(page.Data, !page.HasNextPage()); !getNextPage {
259 return page.Error
260 }
261 }
262
263 return nil
264 }