123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package qs
- import (
- "errors"
- "net/http"
- "net/url"
- "strconv"
- )
- var (
- ErrInvalidLimit = errors.New("invalid limit")
- ErrInvalidOffset = errors.New("invalid offset")
- ErrInvalidPage = errors.New("invalid page")
- )
- type Pagination struct {
- Limit int `json:"limit"`
- Offset int `json:"offset"`
- Page int `json:"page,omitempty"`
- }
- type ReadPaginationOptions struct {
- LimitKey string
- OffsetKey string
- PageKey string
- MaxLimit int
- MinLimit int
- }
- func ReadPagination(values url.Values, opt *ReadPaginationOptions) (*Pagination, error) {
- opt = initPaginationOptions(opt)
- limit := 0
- offset := 0
- page := 0
- var err error = nil
- if values.Has(opt.LimitKey) {
- limit, err = strconv.Atoi(values.Get(opt.LimitKey))
- if err != nil {
- return nil, ErrInvalidLimit
- }
- }
- if opt.MaxLimit > 0 && limit > opt.MaxLimit {
- limit = opt.MaxLimit
- } else if limit < opt.MinLimit {
- limit = opt.MinLimit
- }
- if values.Has(opt.OffsetKey) {
- offset, err = strconv.Atoi(values.Get(opt.OffsetKey))
- if err != nil {
- return nil, ErrInvalidOffset
- }
- } else if values.Has(opt.PageKey) {
- page, err = strconv.Atoi(values.Get(opt.PageKey))
- if err != nil {
- return nil, ErrInvalidPage
- }
- offset = (page - 1) * limit
- }
- pag := &Pagination{
- Limit: limit,
- Offset: offset,
- Page: page,
- }
- return pag, nil
- }
- func ReadRequestPagination(req *http.Request, opt *ReadPaginationOptions) (*Pagination, error) {
- return ReadPagination(req.URL.Query(), opt)
- }
- func ReadStringPagination(qs string, opt *ReadPaginationOptions) (*Pagination, error) {
- values, err := url.ParseQuery(qs)
- if err != nil {
- return nil, err
- }
- return ReadPagination(values, opt)
- }
- func initPaginationOptions(opt *ReadPaginationOptions) *ReadPaginationOptions {
- def := &ReadPaginationOptions{
- LimitKey: "limit",
- OffsetKey: "offset",
- PageKey: "page",
- }
- if opt != nil {
- if len(opt.LimitKey) > 0 {
- def.LimitKey = opt.LimitKey
- }
- if len(opt.OffsetKey) > 0 {
- def.OffsetKey = opt.OffsetKey
- }
- if len(opt.PageKey) > 0 {
- def.PageKey = opt.PageKey
- }
- if opt.MaxLimit > def.MaxLimit {
- def.MaxLimit = opt.MaxLimit
- }
- if opt.MinLimit > def.MinLimit {
- def.MinLimit = opt.MinLimit
- }
- }
- return def
- }
|