resource_list.go raw

   1  package bunny
   2  
   3  import "context"
   4  
   5  const (
   6  	// DefaultPaginationPage is the default value that is used for
   7  	// PaginationOptions.Page if it is unset.
   8  	DefaultPaginationPage = 1
   9  	// DefaultPaginationPerPage is the default value that is used for
  10  	// PaginationOptions.PerPage if it is unset.
  11  	DefaultPaginationPerPage = 1000
  12  )
  13  
  14  // PaginationOptions specifies optional parameters for List APIs.
  15  type PaginationOptions struct {
  16  	// Page the page to return
  17  	Page int32 `url:"page,omitempty"`
  18  	// PerPage how many entries to return per page
  19  	PerPage int32 `url:"per_page,omitempty"`
  20  }
  21  
  22  // PaginationReply represents the pagination information contained in a
  23  // List API endpoint response.
  24  //
  25  // Ex. Bunny.net API docs:
  26  // - https://docs.bunny.net/reference/pullzonepublic_index
  27  // - https://docs.bunny.net/reference/storagezonepublic_index
  28  type PaginationReply[Item any] struct {
  29  	Items        []*Item `json:"Items,omitempty"`
  30  	CurrentPage  *int32  `json:"CurrentPage"`
  31  	TotalItems   *int32  `json:"TotalItems"`
  32  	HasMoreItems *bool   `json:"HasMoreItems"`
  33  }
  34  
  35  func (p *PaginationOptions) ensureConstraints() {
  36  	if p.Page < 1 {
  37  		p.Page = DefaultPaginationPage
  38  	}
  39  
  40  	if p.PerPage < 1 {
  41  		p.PerPage = DefaultPaginationPerPage
  42  	}
  43  }
  44  
  45  func resourceList[Resp any](ctx context.Context, client *Client, path string, opts *PaginationOptions) (*Resp, error) {
  46  	// Ensure that opts.Page is >=1, if it isn't bunny.net will send a
  47  	// different response JSON object, that contains only a single Object,
  48  	// without items and paginations fields. Enforcing opts.page =>1 ensures
  49  	// that we always unmarshall into the same struct.
  50  	if opts == nil {
  51  		opts = &PaginationOptions{
  52  			Page:    DefaultPaginationPage,
  53  			PerPage: DefaultPaginationPerPage,
  54  		}
  55  	} else {
  56  		opts.ensureConstraints()
  57  	}
  58  
  59  	req, err := client.newGetRequest(path, opts)
  60  	if err != nil {
  61  		return nil, err
  62  	}
  63  
  64  	var res Resp
  65  
  66  	if err := client.sendRequest(ctx, req, &res); err != nil {
  67  		return nil, err
  68  	}
  69  
  70  	return &res, nil
  71  }
  72