66 lines
1.7 KiB
Go
66 lines
1.7 KiB
Go
|
package response
|
||
|
|
||
|
import (
|
||
|
"net/url"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
// PaginationMeta is a structure included in responses for pagination.
|
||
|
type PaginationMeta struct {
|
||
|
Limit int `json:"limit"`
|
||
|
CurrentOffset int `json:"current_offset"`
|
||
|
NextOffset *int `json:"next_offset,omitempty"`
|
||
|
PrevOffset *int `json:"prev_offset,omitempty"`
|
||
|
NextURL string `json:"next_url,omitempty"`
|
||
|
PrevURL string `json:"prev_url,omitempty"`
|
||
|
}
|
||
|
|
||
|
// NewPaginationMeta populates pagination meta data from result parameters
|
||
|
func NewPaginationMeta(offset, limit int, hasMore bool, currentURL string) PaginationMeta {
|
||
|
pm := PaginationMeta{
|
||
|
Limit: limit,
|
||
|
CurrentOffset: offset,
|
||
|
}
|
||
|
|
||
|
// Calculate next/prev offsets, leave nil if not valid pages
|
||
|
nextOffset := offset + limit
|
||
|
if hasMore {
|
||
|
pm.NextOffset = &nextOffset
|
||
|
}
|
||
|
|
||
|
prevOffset := offset - limit
|
||
|
if prevOffset < 0 {
|
||
|
prevOffset = 0
|
||
|
}
|
||
|
if prevOffset < offset {
|
||
|
pm.PrevOffset = &prevOffset
|
||
|
}
|
||
|
|
||
|
// If URL format provided, populate URLs. Intentionally swallow URL errors for now, API should
|
||
|
// catch missing URLs if we call with bad URL arg (and we care about them being present).
|
||
|
if currentURL != "" && pm.NextOffset != nil {
|
||
|
pm.NextURL, _ = setQueryParam(currentURL, "offset", *pm.NextOffset, 0)
|
||
|
}
|
||
|
if currentURL != "" && pm.PrevOffset != nil {
|
||
|
pm.PrevURL, _ = setQueryParam(currentURL, "offset", *pm.PrevOffset, 0)
|
||
|
}
|
||
|
|
||
|
return pm
|
||
|
}
|
||
|
|
||
|
func setQueryParam(baseURL, key string, val, defaultVal int) (string, error) {
|
||
|
u, err := url.Parse(baseURL)
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
q := u.Query()
|
||
|
if val == defaultVal {
|
||
|
// elide param if it's the default value
|
||
|
q.Del(key)
|
||
|
} else {
|
||
|
q.Set(key, strconv.Itoa(val))
|
||
|
}
|
||
|
u.RawQuery = q.Encode()
|
||
|
return u.String(), nil
|
||
|
}
|