-
Notifications
You must be signed in to change notification settings - Fork 80
/
Copy pathiterator.go
139 lines (120 loc) · 4.61 KB
/
iterator.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package zendesk
import (
"context"
)
// PaginationOptions struct represents general pagination options.
// PageSize specifies the number of items per page, IsCBP indicates if it's cursor-based pagination,
// SortBy and SortOrder describe how to sort the items in Offset Based Pagination, and Sort describes how to sort items in Cursor Based Pagination.
type PaginationOptions struct {
CommonOptions
PageSize int //default is 100
IsCBP bool //default is true
}
// NewPaginationOptions() returns a pointer to a new PaginationOptions struct with default values (PageSize is 100, IsCBP is true).
func NewPaginationOptions() *PaginationOptions {
return &PaginationOptions{
PageSize: 100,
IsCBP: true,
}
}
type CommonOptions struct {
Active bool `url:"active,omitempty"`
Role string `url:"role,omitempty"`
Roles []string `url:"role[],omitempty"`
PermissionSet int64 `url:"permission_set,omitempty"`
// SortBy can take "assignee", "assignee.name", "created_at", "group", "id",
// "locale", "requester", "requester.name", "status", "subject", "updated_at"
SortBy string `url:"sort_by,omitempty"`
// SortOrder can take "asc" or "desc"
SortOrder string `url:"sort_order,omitempty"`
Sort string `url:"sort,omitempty"`
Id int64
GroupID int64 `json:"group_id,omitempty" url:"group_id,omitempty"`
UserID int64 `json:"user_id,omitempty" url:"user_id,omitempty"`
OrganizationID int64 `json:"organization_id,omitempty" url:"organization_id,omitempty"`
Access string `json:"access"`
Category int `json:"category"`
Include string `json:"include" url:"include,omitempty"`
OnlyViewable bool `json:"only_viewable"`
Query string `url:"query"`
EndUserVisible bool `url:"end_user_visible,omitempty"`
FallbackToDefault bool `url:"fallback_to_default,omitempty"`
AssociatedToBrand bool `url:"associated_to_brand,omitempty"`
CategoryID string `url:"category_id,omitempty"`
IncludeInlineImages string `url:"include_inline_images,omitempty"`
}
// CBPOptions struct is used to specify options for listing objects in CBP (Cursor Based Pagination).
// It embeds the CursorPagination struct for pagination and provides an option Sort for sorting the result.
type CBPOptions struct {
CursorPagination
CommonOptions
}
// OBPOptions struct is used to specify options for listing objects in OBP (Offset Based Pagination).
// It embeds the PageOptions struct for pagination and provides options for sorting the result;
// SortBy specifies the field to sort by, and SortOrder specifies the order (either 'asc' or 'desc').
type OBPOptions struct {
PageOptions
CommonOptions
}
// ObpFunc defines the signature of the function used to list objects in OBP.
type ObpFunc[T any] func(ctx context.Context, opts *OBPOptions) ([]T, Page, error)
// CbpFunc defines the signature of the function used to list objects in CBP.
type CbpFunc[T any] func(ctx context.Context, opts *CBPOptions) ([]T, CursorPaginationMeta, error)
// terator struct provides a convenient and genric way to iterate over pages of objects in either OBP or CBP.
// It holds state for iteration, including the current page size, a flag indicating more pages, pagination type (OBP or CBP), and sorting options.
type Iterator[T any] struct {
CommonOptions
// generic fields
pageSize int
hasMore bool
isCBP bool
// OBP fields
pageIndex int
// CBP fields
pageAfter string
// common fields
ctx context.Context
obpFunc ObpFunc[T]
cbpFunc CbpFunc[T]
}
// HasMore() returns a boolean indicating whether more pages are available for iteration.
func (i *Iterator[T]) HasMore() bool {
return i.hasMore
}
// GetNext() retrieves the next batch of objects according to the current pagination and sorting options.
// It updates the state of the iterator for subsequent calls.
// In case of an error, it sets hasMore to false and returns an error.
func (i *Iterator[T]) GetNext() ([]T, error) {
if !i.isCBP {
obpOps := &OBPOptions{
PageOptions: PageOptions{
PerPage: i.pageSize,
Page: i.pageIndex,
},
CommonOptions: i.CommonOptions,
}
results, page, err := i.obpFunc(i.ctx, obpOps)
if err != nil {
i.hasMore = false
return nil, err
}
i.hasMore = page.HasNext()
i.pageIndex++
return results, nil
}
cbpOps := &CBPOptions{
CursorPagination: CursorPagination{
PageSize: i.pageSize,
PageAfter: i.pageAfter,
},
CommonOptions: i.CommonOptions,
}
results, meta, err := i.cbpFunc(i.ctx, cbpOps)
if err != nil {
i.hasMore = false
return nil, err
}
i.hasMore = meta.HasMore
i.pageAfter = meta.AfterCursor
return results, nil
}