github.com/stripe/stripe-go/v76@v76.25.0/search_iter.go (about) 1 package stripe 2 3 import ( 4 "reflect" 5 6 "github.com/stripe/stripe-go/v76/form" 7 ) 8 9 // 10 // Public constants 11 // 12 13 // Contains constants for the names of parameters used for pagination in search APIs. 14 const ( 15 Page = "page" 16 ) 17 18 // 19 // Public types 20 // 21 22 // SearchIter provides a convenient interface 23 // for iterating over the elements 24 // returned from paginated search API calls. 25 // Successive calls to the Next method 26 // will step through each item in the search results, 27 // fetching pages of items as needed. 28 // Iterators are not thread-safe, so they should not be consumed 29 // across multiple goroutines. 30 type SearchIter struct { 31 cur interface{} 32 err error 33 formValues *form.Values 34 searchContainer SearchContainer 35 searchParams SearchParams 36 meta *SearchMeta 37 query SearchQuery 38 values []interface{} 39 } 40 41 // Current returns the most recent item 42 // visited by a call to Next. 43 func (it *SearchIter) Current() interface{} { 44 return it.cur 45 } 46 47 // Err returns the error, if any, 48 // that caused the SearchIter to stop. 49 // It must be inspected 50 // after Next returns false. 51 func (it *SearchIter) Err() error { 52 return it.err 53 } 54 55 // SearchResult returns the current search result container which the iterator is currently using. 56 // Objects will change as new API calls are made to continue pagination. 57 func (it *SearchIter) SearchResult() SearchContainer { 58 return it.searchContainer 59 } 60 61 // Meta returns the search metadata. 62 func (it *SearchIter) Meta() *SearchMeta { 63 return it.meta 64 } 65 66 // Next advances the SearchIter to the next item in the search results, 67 // which will then be available 68 // through the Current method. 69 // It returns false when the iterator stops 70 // at the end of the search results. 71 func (it *SearchIter) Next() bool { 72 if len(it.values) == 0 && it.meta.HasMore && !it.searchParams.Single { 73 if it.meta.NextPage != nil { 74 it.formValues.Set(Page, *it.meta.NextPage) 75 it.getPage() 76 } 77 } 78 if len(it.values) == 0 { 79 return false 80 } 81 it.cur = it.values[0] 82 it.values = it.values[1:] 83 return true 84 } 85 86 func (it *SearchIter) getPage() { 87 it.values, it.searchContainer, it.err = it.query(it.searchParams.GetParams(), it.formValues) 88 it.meta = it.searchContainer.GetSearchMeta() 89 } 90 91 // SearchQuery is the function used to get search results. 92 type SearchQuery func(*Params, *form.Values) ([]interface{}, SearchContainer, error) 93 94 // 95 // Public functions 96 // 97 98 // GetSearchIter returns a new SearchIter for a given query and its options. 99 func GetSearchIter(container SearchParamsContainer, query SearchQuery) *SearchIter { 100 var searchParams *SearchParams 101 formValues := &form.Values{} 102 103 if container != nil { 104 reflectValue := reflect.ValueOf(container) 105 106 // See the comment on Call in stripe.go. 107 if reflectValue.Kind() == reflect.Ptr && !reflectValue.IsNil() { 108 searchParams = container.GetSearchParams() 109 form.AppendTo(formValues, container) 110 } 111 } 112 113 if searchParams == nil { 114 searchParams = &SearchParams{} 115 } 116 iter := &SearchIter{ 117 formValues: formValues, 118 searchParams: *searchParams, 119 query: query, 120 } 121 122 iter.getPage() 123 124 return iter 125 }