github.com/hernad/nomad@v1.6.112/nomad/state/paginator/tokenizer.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package paginator 5 6 import ( 7 "fmt" 8 "strings" 9 ) 10 11 // Tokenizer is the interface that must be implemented to provide pagination 12 // tokens to the Paginator. 13 type Tokenizer interface { 14 // GetToken returns the pagination token for the given element. 15 GetToken(interface{}) string 16 } 17 18 // IDGetter is the interface that must be implemented by structs that need to 19 // have their ID as part of the pagination token. 20 type IDGetter interface { 21 GetID() string 22 } 23 24 // NamespaceGetter is the interface that must be implemented by structs that 25 // need to have their Namespace as part of the pagination token. 26 type NamespaceGetter interface { 27 GetNamespace() string 28 } 29 30 // CreateIndexGetter is the interface that must be implemented by structs that 31 // need to have their CreateIndex as part of the pagination token. 32 type CreateIndexGetter interface { 33 GetCreateIndex() uint64 34 } 35 36 // StructsTokenizerOptions is the configuration provided to a StructsTokenizer. 37 // 38 // These are some of the common use cases: 39 // 40 // Structs that can be uniquely identified with only its own ID: 41 // 42 // StructsTokenizerOptions { 43 // WithID: true, 44 // } 45 // 46 // Structs that are only unique within their namespace: 47 // 48 // StructsTokenizerOptions { 49 // WithID: true, 50 // WithNamespace: true, 51 // } 52 // 53 // Structs that can be sorted by their create index should also set 54 // `WithCreateIndex` to `true` along with the other options: 55 // 56 // StructsTokenizerOptions { 57 // WithID: true, 58 // WithNamespace: true, 59 // WithCreateIndex: true, 60 // } 61 type StructsTokenizerOptions struct { 62 WithCreateIndex bool 63 WithNamespace bool 64 WithID bool 65 } 66 67 // StructsTokenizer is an pagination token generator that can create different 68 // formats of pagination tokens based on common fields found in the structs 69 // package. 70 type StructsTokenizer struct { 71 opts StructsTokenizerOptions 72 } 73 74 // NewStructsTokenizer returns a new StructsTokenizer. 75 func NewStructsTokenizer(_ Iterator, opts StructsTokenizerOptions) StructsTokenizer { 76 return StructsTokenizer{ 77 opts: opts, 78 } 79 } 80 81 func (it StructsTokenizer) GetToken(raw interface{}) string { 82 if raw == nil { 83 return "" 84 } 85 86 parts := []string{} 87 88 if it.opts.WithCreateIndex { 89 token := raw.(CreateIndexGetter).GetCreateIndex() 90 parts = append(parts, fmt.Sprintf("%v", token)) 91 } 92 93 if it.opts.WithNamespace { 94 token := raw.(NamespaceGetter).GetNamespace() 95 parts = append(parts, token) 96 } 97 98 if it.opts.WithID { 99 token := raw.(IDGetter).GetID() 100 parts = append(parts, token) 101 } 102 103 // Use a character that is not part of validNamespaceName as separator to 104 // avoid accidentally generating collisions. 105 // For example, namespace `a` and job `b-c` would collide with namespace 106 // `a-b` and job `c` into the same token `a-b-c`, since `-` is an allowed 107 // character in namespace. 108 return strings.Join(parts, ".") 109 }