-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
tokenizer.go
105 lines (91 loc) · 2.85 KB
/
tokenizer.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
package paginator
import (
"fmt"
"strings"
)
// Tokenizer is the interface that must be implemented to provide pagination
// tokens to the Paginator.
type Tokenizer interface {
// GetToken returns the pagination token for the given element.
GetToken(interface{}) string
}
// IDGetter is the interface that must be implemented by structs that need to
// have their ID as part of the pagination token.
type IDGetter interface {
GetID() string
}
// NamespaceGetter is the interface that must be implemented by structs that
// need to have their Namespace as part of the pagination token.
type NamespaceGetter interface {
GetNamespace() string
}
// CreateIndexGetter is the interface that must be implemented by structs that
// need to have their CreateIndex as part of the pagination token.
type CreateIndexGetter interface {
GetCreateIndex() uint64
}
// StructsTokenizerOptions is the configuration provided to a StructsTokenizer.
//
// These are some of the common use cases:
// - Structs that can be uniquely identified with only its own ID:
//
// StructsTokenizerOptions {
// WithID: true,
// }
//
// - Structs that are only unique within their namespace:
//
// StructsTokenizerOptions {
// WithID: true,
// WithNamespace: true,
// }
//
// - Structs that can be sorted by their create index should also set
// `WithCreateIndex` to `true` along with the other options:
//
// StructsTokenizerOptions {
// WithID: true,
// WithNamespace: true,
// WithCreateIndex: true,
// }
type StructsTokenizerOptions struct {
WithCreateIndex bool
WithNamespace bool
WithID bool
}
// StructsTokenizer is an pagination token generator that can create different
// formats of pagination tokens based on common fields found in the structs
// package.
type StructsTokenizer struct {
opts StructsTokenizerOptions
}
// NewStructsTokenizer returns a new StructsTokenizer.
func NewStructsTokenizer(_ Iterator, opts StructsTokenizerOptions) StructsTokenizer {
return StructsTokenizer{
opts: opts,
}
}
func (it StructsTokenizer) GetToken(raw interface{}) string {
if raw == nil {
return ""
}
parts := []string{}
if it.opts.WithCreateIndex {
token := raw.(CreateIndexGetter).GetCreateIndex()
parts = append(parts, fmt.Sprintf("%v", token))
}
if it.opts.WithNamespace {
token := raw.(NamespaceGetter).GetNamespace()
parts = append(parts, token)
}
if it.opts.WithID {
token := raw.(IDGetter).GetID()
parts = append(parts, token)
}
// Use a character that is not part of validNamespaceName as separator to
// avoid accidentally generating collisions.
// For example, namespace `a` and job `b-c` would collide with namespace
// `a-b` and job `c` into the same token `a-b-c`, since `-` is an allowed
// character in namespace.
return strings.Join(parts, ".")
}