enumcache

package
v1.146.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package enumcache provides thread-safe storage and lookup for enumeration name and ID mappings.

It solves the problem of maintaining reusable bidirectional enum mappings in concurrent applications, including support for bitmask-based enum sets.

The cache is useful when you need fast mapping from string names to integer IDs and back again. It also supports encoding and decoding enum bitmaps when enum IDs represent bit flags.

Typical usage is set-once, read-many: populate entries during startup using Set, SetAllIDByName, or SetAllNameByID, then perform lookups from application code.

Top features:

  • concurrent-safe name-to-ID and ID-to-name lookup guarded by an internal read/write mutex
  • bulk population helpers for loading enum definitions from code or external sources
  • deterministic sorted retrieval with SortNames and SortIDs for logs, output, and tests
  • binary-map encoding and decoding via github.com/tecnickcom/nurago/pkg/enumbitmap for flag-style enum values
  • explicit error returns when IDs or names are missing, improving caller control

Benefits:

  • keep enum mappings centralized and thread-safe
  • reduce duplication of lookup logic across services
  • simplify support for feature flags and bitmask enums

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNameNotFound is returned by ID when the requested name is not cached.
	// Match it with errors.Is.
	ErrNameNotFound = errors.New("enumcache: name not found")

	// ErrIDNotFound is returned by Name when the requested id is not cached.
	// Match it with errors.Is.
	ErrIDNotFound = errors.New("enumcache: ID not found")
)

Functions

This section is empty.

Types

type EnumCache

type EnumCache struct {
	// contains filtered or unexported fields
}

EnumCache stores bidirectional enum mappings (name<->ID).

func New

func New() *EnumCache

New creates an empty thread-safe enum cache.

The cache supports bidirectional name/id lookups and bitmask conversions.

Example
package main

import (
	"fmt"
	"log"

	"github.com/tecnickcom/nurago/pkg/enumcache"
)

func main() {
	// create a new cache
	ec := enumcache.New()

	// add an entry
	ec.Set(1, "alpha")

	// get the numerical ID associated to a string
	id, err := ec.ID("alpha")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(id)

	// get the string name associated to a numerical ID
	name, err := ec.Name(1)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(name)

}
Output:
1
alpha

func (*EnumCache) DecodeBinaryMap

func (ec *EnumCache) DecodeBinaryMap(v int) ([]string, error)

DecodeBinaryMap expands a bitmask value into enum names.

The cache must contain bit-value IDs (single-bit powers of two, 1<<0 through 1<<31) mapped to names; IDs that are 0 or multi-bit cannot be decoded and are silently unreachable. On unknown set bits the returned error wraps enumbitmap.ErrUnknownBitValues while known names are still returned.

Example
package main

import (
	"fmt"
	"log"

	"github.com/tecnickcom/nurago/pkg/enumcache"
)

func main() {
	// create a new cache
	ec := enumcache.New()

	ec.Set(1, "first")    // 00000001
	ec.Set(2, "second")   // 00000010
	ec.Set(4, "third")    // 00000100
	ec.Set(8, "fourth")   // 00001000
	ec.Set(16, "fifth")   // 00010000
	ec.Set(32, "sixth")   // 00100000
	ec.Set(64, "seventh") // 01000000
	ec.Set(128, "eighth") // 10000000

	// convert binary code to a slice of strings
	s, err := ec.DecodeBinaryMap(0b00101010) // 42
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(s)

}
Output:
[second fourth sixth]

func (*EnumCache) Delete

func (ec *EnumCache) Delete(id int)

Delete removes the mapping for id together with its associated name.

It is a no-op when id is not present. Both internal maps are kept consistent.

func (*EnumCache) EncodeBinaryMap

func (ec *EnumCache) EncodeBinaryMap(s []string) (int, error)

EncodeBinaryMap combines enum names into a bitmask value.

The cache must contain bit-value IDs (single-bit powers of two, 1<<0 through 1<<31) mapped to names for the result to round-trip through DecodeBinaryMap. On unknown names the returned error wraps enumbitmap.ErrUnknownStringValues while known names are still combined into the bitmask.

Example
package main

import (
	"fmt"
	"log"

	"github.com/tecnickcom/nurago/pkg/enumcache"
)

func main() {
	// create a new cache
	ec := enumcache.New()

	ec.Set(1, "first")    // 00000001
	ec.Set(2, "second")   // 00000010
	ec.Set(4, "third")    // 00000100
	ec.Set(8, "fourth")   // 00001000
	ec.Set(16, "fifth")   // 00010000
	ec.Set(32, "sixth")   // 00100000
	ec.Set(64, "seventh") // 01000000
	ec.Set(128, "eighth") // 10000000

	// convert a slice of string to the equivalent binary code
	v, err := ec.EncodeBinaryMap([]string{"second", "fourth", "sixth"})
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(v)

}
Output:
42

func (*EnumCache) Has

func (ec *EnumCache) Has(name string) bool

Has reports whether name is present in the cache.

func (*EnumCache) HasID

func (ec *EnumCache) HasID(id int) bool

HasID reports whether id is present in the cache.

func (*EnumCache) ID

func (ec *EnumCache) ID(name string) (int, error)

ID returns the numeric ID associated with name.

It returns an error wrapping ErrNameNotFound when name is not present.

func (*EnumCache) Len

func (ec *EnumCache) Len() int

Len returns the number of cached enum pairs.

func (*EnumCache) Name

func (ec *EnumCache) Name(id int) (string, error)

Name returns the symbolic name associated with id.

It returns an error wrapping ErrIDNotFound when id is not present.

func (*EnumCache) Set

func (ec *EnumCache) Set(id int, name string)

Set stores a single enum mapping pair.

Existing values for id or name are overwritten. When the id or name was previously associated with a different counterpart, the stale reverse mapping is removed so both directions stay consistent.

func (*EnumCache) SetAllIDByName

func (ec *EnumCache) SetAllIDByName(enum IDByName)

SetAllIDByName bulk-loads enum values from name-to-id input.

It is useful when parsing static definitions keyed by symbolic names.

Example
package main

import (
	"fmt"
	"log"

	"github.com/tecnickcom/nurago/pkg/enumcache"
)

func main() {
	// create a new cache
	ec := enumcache.New()

	// define cache entries indexed by string
	e := enumcache.IDByName{
		"first":  11,
		"second": 23,
		"third":  31,
	}

	// populate the cache with the specified entries
	ec.SetAllIDByName(e)

	// get the numerical ID associated to a string
	id, err := ec.ID("second")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(id)

	// get the string name associated to a numerical ID
	name, err := ec.Name(23)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(name)

}
Output:
23
second

func (*EnumCache) SetAllNameByID

func (ec *EnumCache) SetAllNameByID(enum NameByID)

SetAllNameByID bulk-loads enum values from id-to-name input.

It is useful when loading rows from storage keyed by numeric IDs.

Example
package main

import (
	"fmt"
	"log"

	"github.com/tecnickcom/nurago/pkg/enumcache"
)

func main() {
	// create a new cache
	ec := enumcache.New()

	// define cache entries indexed by numerical ID
	e := enumcache.NameByID{
		11: "first",
		23: "second",
		31: "third",
	}

	// populate the cache with the specified entries
	ec.SetAllNameByID(e)

	// get the numerical ID associated to a string
	id, err := ec.ID("second")
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(id)

	// get the string name associated to a numerical ID
	name, err := ec.Name(23)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(name)

}
Output:
23
second

func (*EnumCache) SortIDs

func (ec *EnumCache) SortIDs() []int

SortIDs returns all cached IDs in ascending numeric order.

This is useful for deterministic output and tests.

Example
package main

import (
	"fmt"

	"github.com/tecnickcom/nurago/pkg/enumcache"
)

func main() {
	// create a new cache
	ec := enumcache.New()

	// define cache entries indexed by numerical ID
	e := enumcache.NameByID{
		55: "delta",
		33: "charlie",
		22: "bravo",
		66: "foxtrot",
		44: "echo",
		11: "alpha",
	}

	// populate the cache with the specified entries
	ec.SetAllNameByID(e)

	// get the sorted list of IDs
	sorted := ec.SortIDs()

	fmt.Println(sorted)

}
Output:
[11 22 33 44 55 66]

func (*EnumCache) SortNames

func (ec *EnumCache) SortNames() []string

SortNames returns all cached names in ascending lexical order.

This is useful for deterministic output and tests.

Example
package main

import (
	"fmt"

	"github.com/tecnickcom/nurago/pkg/enumcache"
)

func main() {
	// create a new cache
	ec := enumcache.New()

	// define cache entries indexed by numerical ID
	e := enumcache.NameByID{
		1:  "delta",
		2:  "charlie",
		4:  "bravo",
		8:  "foxtrot",
		16: "echo",
		32: "alpha",
	}

	// populate the cache with the specified entries
	ec.SetAllNameByID(e)

	// get the sorted list of names
	sorted := ec.SortNames()

	fmt.Println(sorted)

}
Output:
[alpha bravo charlie delta echo foxtrot]

type IDByName

type IDByName map[string]int

IDByName maps enum names to numeric IDs.

type NameByID

type NameByID map[int]string

NameByID maps integers to string names.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL