github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/nomad/state/paginator/tokenizer.go (about)

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