-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathpika_page_token.go
120 lines (96 loc) · 2.67 KB
/
pika_page_token.go
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// SPDX-FileCopyrightText: Copyright (c) 2023-2024, Ctrl IQ, Inc. All rights reserved
// SPDX-License-Identifier: Apache-2.0
package pika
import (
"encoding/base64"
"encoding/json"
"fmt"
)
type PageToken[T any] struct {
QuerySet[T] `json:"-"`
Offset uint `json:"offset"`
Filter string `json:"filter"`
OrderBy string `json:"order_by"`
PageSize uint `json:"page_size"`
}
type Paginatable interface {
GetFilter() string
GetOrderBy() string
GetPageSize() int32
GetPageToken() string
}
type PageRequest struct {
// Filter is a filter expression that restricts the results to return.
Filter string
// OrderBy is a comma-separated list of fields to order by.
OrderBy string
// PageSize is the maximum number of results to return.
PageSize int32
// PageToken is the page token to use for the next request.
PageToken string
}
func NewPageToken[T any]() *PageToken[T] {
return &PageToken[T]{}
}
// Encode marshals the PageToken to a base64-encoded string
func (p *PageToken[T]) Encode() (string, error) {
// Page token with page size 0 is useless
if p.PageSize == 0 {
return "", nil
}
data, err := json.Marshal(p)
if err != nil {
return "", fmt.Errorf("failed to marshal json: %w", err)
}
return base64.URLEncoding.EncodeToString(data), nil
}
// Decode constructs a PageToken from a base64-encoded string
func (p *PageToken[T]) Decode(s string) error {
data, err := base64.URLEncoding.DecodeString(s)
if err != nil {
return fmt.Errorf("failed to decode page token, make sure it is from a previous request")
}
return json.Unmarshal(data, p)
}
func (p *PageToken[T]) pageToken(b QuerySet[T], options AIPFilterOptions) (QuerySet[T], error) {
if p.OrderBy != "" {
orderBy, err := options.verifyOrderBy(p.OrderBy)
if err != nil {
return nil, fmt.Errorf("applying order by from page token: %w (%s)", err, p.OrderBy)
}
b.OrderBy(orderBy...)
}
// Default page size is 25
if p.PageSize == 0 {
p.PageSize = 25
}
// Return error if page size is less than 1
if p.PageSize < 1 {
return nil, fmt.Errorf("page size cannot be less than 1")
}
// Return error if page size is greater than 100
if p.PageSize > 100 {
return nil, fmt.Errorf("page size cannot be greater than 100")
}
b.Offset(int(p.Offset))
b.Limit(int(p.PageSize))
if p.Filter != "" {
_, err := b.AIP160(p.Filter, options)
if err != nil {
return nil, fmt.Errorf("applying filter from page token: %w", err)
}
}
return b, nil
}
func (p *PageRequest) GetFilter() string {
return p.Filter
}
func (p *PageRequest) GetOrderBy() string {
return p.OrderBy
}
func (p *PageRequest) GetPageSize() int32 {
return p.PageSize
}
func (p *PageRequest) GetPageToken() string {
return p.PageToken
}