github.com/hashicorp/terraform-plugin-sdk@v1.17.2/internal/registry/response/pagination.go (about)

     1  package response
     2  
     3  import (
     4  	"net/url"
     5  	"strconv"
     6  )
     7  
     8  // PaginationMeta is a structure included in responses for pagination.
     9  type PaginationMeta struct {
    10  	Limit         int    `json:"limit"`
    11  	CurrentOffset int    `json:"current_offset"`
    12  	NextOffset    *int   `json:"next_offset,omitempty"`
    13  	PrevOffset    *int   `json:"prev_offset,omitempty"`
    14  	NextURL       string `json:"next_url,omitempty"`
    15  	PrevURL       string `json:"prev_url,omitempty"`
    16  }
    17  
    18  // NewPaginationMeta populates pagination meta data from result parameters
    19  func NewPaginationMeta(offset, limit int, hasMore bool, currentURL string) PaginationMeta {
    20  	pm := PaginationMeta{
    21  		Limit:         limit,
    22  		CurrentOffset: offset,
    23  	}
    24  
    25  	// Calculate next/prev offsets, leave nil if not valid pages
    26  	nextOffset := offset + limit
    27  	if hasMore {
    28  		pm.NextOffset = &nextOffset
    29  	}
    30  
    31  	prevOffset := offset - limit
    32  	if prevOffset < 0 {
    33  		prevOffset = 0
    34  	}
    35  	if prevOffset < offset {
    36  		pm.PrevOffset = &prevOffset
    37  	}
    38  
    39  	// If URL format provided, populate URLs. Intentionally swallow URL errors for now, API should
    40  	// catch missing URLs if we call with bad URL arg (and we care about them being present).
    41  	if currentURL != "" && pm.NextOffset != nil {
    42  		pm.NextURL, _ = setQueryParam(currentURL, "offset", *pm.NextOffset, 0)
    43  	}
    44  	if currentURL != "" && pm.PrevOffset != nil {
    45  		pm.PrevURL, _ = setQueryParam(currentURL, "offset", *pm.PrevOffset, 0)
    46  	}
    47  
    48  	return pm
    49  }
    50  
    51  func setQueryParam(baseURL, key string, val, defaultVal int) (string, error) {
    52  	u, err := url.Parse(baseURL)
    53  	if err != nil {
    54  		return "", err
    55  	}
    56  	q := u.Query()
    57  	if val == defaultVal {
    58  		// elide param if it's the default value
    59  		q.Del(key)
    60  	} else {
    61  		q.Set(key, strconv.Itoa(val))
    62  	}
    63  	u.RawQuery = q.Encode()
    64  	return u.String(), nil
    65  }