github.com/IBM-Cloud/bluemix-go@v0.0.0-20240314082800-4e02a69b84b2/api/cis/cisv1/paginate.go (about) 1 package cisv1 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "reflect" 7 "strings" 8 ) 9 10 type GenericPaginatedResourcesHandler struct { 11 resourceType reflect.Type 12 } 13 14 func NewDNSPaginatedResources(resource interface{}) GenericPaginatedResourcesHandler { 15 return GenericPaginatedResourcesHandler{ 16 resourceType: reflect.TypeOf(resource), 17 } 18 } 19 20 func (pr GenericPaginatedResourcesHandler) Resources(bytes []byte, curURL string) ([]interface{}, string, error) { 21 var paginatedResources = struct { 22 ResultInfo struct { 23 Page int `json:"page"` 24 TotalPages int `json:"total_pages"` 25 } `json:"result_info"` 26 Result json.RawMessage `json:"result"` 27 }{} 28 29 if err := json.Unmarshal(bytes, &paginatedResources); err != nil { 30 return nil, "", fmt.Errorf("failed to unmarshal paginated response as json: %s", err) 31 } 32 33 slicePtr := reflect.New(reflect.SliceOf(pr.resourceType)) 34 dc := json.NewDecoder(strings.NewReader(string(paginatedResources.Result))) 35 dc.UseNumber() 36 if err := dc.Decode(slicePtr.Interface()); err != nil { 37 return nil, "", fmt.Errorf("failed to decode paginated objects as %T: %s", pr.resourceType, err) 38 } 39 slice := reflect.Indirect(slicePtr) 40 41 contents := make([]interface{}, 0, slice.Len()) 42 for i := 0; i < slice.Len(); i++ { 43 contents = append(contents, slice.Index(i).Interface()) 44 } 45 46 if paginatedResources.ResultInfo.Page >= paginatedResources.ResultInfo.TotalPages { 47 return contents, "", nil 48 } 49 50 return contents, strings.Replace(curURL, fmt.Sprintf("page=%d", paginatedResources.ResultInfo.Page), fmt.Sprintf("page=%d", paginatedResources.ResultInfo.Page+1), 1), nil 51 }