-
-
Notifications
You must be signed in to change notification settings - Fork 187
Expand file tree
/
Copy pathpaginator.go
More file actions
56 lines (47 loc) · 2.12 KB
/
Copy pathpaginator.go
File metadata and controls
56 lines (47 loc) · 2.12 KB
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
package query
import "math"
const (
MinPage = 1 // MinPage represents the minimum allowed value for the pagination query's Page parameter.
MinPerPage = 1 // MinPerPage represents the minimum allowed value for the pagination query's PerPage parameter.
DefaultPerPage = 10 // DefaultPerPage represents the default value for the pagination query's PerPage parameter.
MaxPerPage = 100 // MaxPerPage represents the maximum allowed value for the pagination query's PerPage parameter.
)
// Paginator represents the paginator parameters in a query.
type Paginator struct {
// Page represents the current page number.
Page int `query:"page"`
// PerPage represents the number of items per page.
PerPage int `query:"per_page"`
}
// NewPaginator creates and returns a new Paginator instance with MinPage and DefaultPerPage.
func NewPaginator() *Paginator {
return &Paginator{
Page: MinPage,
PerPage: DefaultPerPage,
}
}
// Normalize ensures valid values for Page and PerPage in the pagination query.
// If query.PerPage is less than zero, it is set to `DefaultPerPage`.
// If query.Page is less than one, it is set to `MinPage`.
// The maximum allowed value for query.PerPage is `MaxPerPage`.
func (p *Paginator) Normalize() {
p.Page = int(math.Max(float64(MinPage), float64(p.Page)))
if p.PerPage == 0 {
p.PerPage = DefaultPerPage
} else {
p.PerPage = int(math.Max(math.Min(float64(p.PerPage), float64(MaxPerPage)), float64(MinPerPage)))
}
}
// Paginated is a request that carries a [Paginator]. Every request type embedding one satisfies it,
// so a caller holding only the request can normalize the page without knowing its concrete type.
//
// The accessor exists because a request embedding both a [Paginator] and a [Sorter] promotes two
// Normalize methods at the same depth, which cancel each other out: neither is reachable through
// the outer type, and no interface over that name can be satisfied.
type Paginated interface {
GetPaginator() *Paginator
}
// GetPaginator returns the paginator itself, satisfying [Paginated] for every type that embeds it.
func (p *Paginator) GetPaginator() *Paginator {
return p
}