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 }