github.com/polygon-io/client-go@v1.16.4/rest/iter/iter.go (about) 1 package iter 2 3 import ( 4 "context" 5 6 "github.com/polygon-io/client-go/rest/encoder" 7 ) 8 9 // ListResponse defines an interface that list API responses must implement. 10 type ListResponse interface { 11 // NextPage returns a URL for retrieving the next page of list results. 12 NextPage() string 13 } 14 15 // Query defines a closure that domain specific iterators must implement. The implementation should 16 // include a call to the API and should return the API response with a separate slice of the results. 17 type Query[T any] func(string) (ListResponse, []T, error) 18 19 // Iter defines an iterator type that list methods should return. The contained type should typically 20 // be a model that's returned in the results of a list method response. 21 type Iter[T any] struct { 22 ctx context.Context 23 query Query[T] 24 25 page ListResponse 26 item T 27 results []T 28 29 err error 30 } 31 32 // NewIter returns a new initialized iterator. This method automatically makes the first query to populate 33 // the results. List methods should use this helper method when building domain specific iterators. 34 func NewIter[T any](ctx context.Context, path string, params any, query Query[T]) *Iter[T] { 35 it := Iter[T]{ 36 ctx: ctx, 37 query: query, 38 } 39 40 uri, err := encoder.New().EncodeParams(path, params) 41 if err != nil { 42 it.err = err 43 return &it 44 } 45 46 it.page, it.results, it.err = it.query(uri) 47 return &it 48 } 49 50 // Next moves the iterator to the next result. 51 func (it *Iter[T]) Next() bool { 52 if it.err != nil { 53 return false 54 } 55 56 if len(it.results) == 0 && it.page.NextPage() != "" { 57 it.page, it.results, it.err = it.query(it.page.NextPage()) 58 } 59 60 if it.err != nil || len(it.results) == 0 { 61 return false 62 } 63 64 it.err = it.ctx.Err() 65 if it.err != nil { 66 return false 67 } 68 69 it.item = it.results[0] 70 it.results = it.results[1:] 71 return true 72 } 73 74 // Item returns the result that the iterator is currently pointing to. 75 func (it *Iter[T]) Item() T { 76 return it.item 77 } 78 79 // Err returns any errors that occur during iteration. 80 func (it *Iter[T]) Err() error { 81 return it.err 82 }