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  }