审查视图

vendor/github.com/go-pg/urlstruct/pager.go 1.5 KB
tangxvhui authored
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
package urlstruct

import (
	"context"
	"net/url"
)

type Pager struct {
	Limit  int `urlstruct:"-"`
	Offset int `urlstruct:"-"`

	// Default max limit is 1000.
	MaxLimit int `urlstruct:"-"`
	// Default max offset is 1000000.
	MaxOffset int `urlstruct:"-"`

	stickyErr error
}

func NewPager(values url.Values) *Pager {
	p := new(Pager)
	p.stickyErr = p.UnmarshalValues(context.TODO(), values)
	return p
}

var _ Unmarshaler = (*Pager)(nil)

func (p *Pager) UnmarshalValues(ctx context.Context, values url.Values) error {
	vs := Values(values)

	limit, err := vs.Int("limit")
	if err != nil {
		return err
	}
	p.Limit = limit

	page, err := vs.Int("page")
	if err != nil {
		return err
	}
	p.SetPage(page)

	return nil
}

func (p *Pager) maxLimit() int {
	if p.MaxLimit > 0 {
		return p.MaxLimit
	}
	return 1000
}

func (p *Pager) maxOffset() int {
	if p.MaxOffset > 0 {
		return p.MaxOffset
	}
	return 1000000
}

func (p *Pager) GetLimit() int {
	const defaultLimit = 100

	if p == nil {
		return defaultLimit
	}
	if p.Limit < 0 {
		return p.Limit
	}
	if p.Limit == 0 {
		return defaultLimit
	}
	if p.Limit > p.maxLimit() {
		return p.maxLimit()
	}
	return p.Limit
}

func (p *Pager) GetOffset() int {
	if p == nil {
		return 0
	}
	if p.Offset > p.maxOffset() {
		return p.maxOffset()
	}
	return p.Offset
}

func (p *Pager) SetPage(page int) {
	if page < 1 {
		page = 1
	}
	p.Offset = (page - 1) * p.GetLimit()
}

func (p *Pager) GetPage() int {
	return (p.GetOffset() / p.GetLimit()) + 1
}