enumnames

package module
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Dec 5, 2023 License: MIT Imports: 5 Imported by: 4

README

enumnames

A small Go package for efficient mapping between integer enum values and string names.

Run go get hermannm.dev/enumnames to add it to your project!

Usage

In the example below, we have a MessageType enum, which we want represented as a uint8 to take up as little space as possible. However, we also want to map each value to a name, for debugging and marshaling/unmarshaling JSON. Here we use enumnames, creating a map that we can then use in our MessageType methods:

import "hermannm.dev/enumnames"

type MessageType uint8

const (
	JoinLobbyMessage MessageType = iota + 1
	ReadyMessage
	StartGameMessage
)

var msgNames = enumnames.NewMap(map[MessageType]string{
	JoinLobbyMessage: "JOIN_LOBBY",
	ReadyMessage:     "READY",
	StartGameMessage: "START_GAME",
})

func (msgType MessageType) IsValid() bool {
	return msgNames.ContainsKey(msgType)
}

func (msgType MessageType) String() string {
	return msgNames.GetNameOrFallback(msgType, "INVALID_MESSAGE_TYPE")
}

func (msgType MessageType) MarshalJSON() ([]byte, error) {
	return msgNames.MarshalToNameJSON(msgType)
}

func (msgType *MessageType) UnmarshalJSON(bytes []byte) error {
	return msgNames.UnmarshalFromNameJSON(bytes, msgType)
}

Benchmarks

Result of running go test -bench=. -benchtime=10s:

goos: linux
goarch: amd64
pkg: hermannm.dev/enumnames
cpu: AMD Ryzen 7 PRO 6850U with Radeon Graphics
BenchmarkGetName-16           	1000000000	         0.7659 ns/op
BenchmarkGetNameWithMap-16    	1000000000	         7.797 ns/op
BenchmarkGetKey-16            	1000000000	         5.988 ns/op
BenchmarkGetKeyWithMap-16     	1000000000	         9.355 ns/op
PASS
ok  	hermannm.dev/enumnames	26.329s

The benchmarks use a uint8 as the enum type, with 255 variants. We see that BenchmarkGetName, which uses enumnames.Map, is 10x faster than BenchmarkGetNameWithMap, which uses a map[uint8]string. The reverse lookup, BenchmarkGetKey, is 50% faster than BenchmarkGetKeyWithMap, which uses a map[string]uint8.

Documentation

Overview

Package enumnames provides efficient mapping between integer enum values and string names.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type IntegerEnum

type IntegerEnum interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}

type Map

type Map[Enum IntegerEnum] struct {
	// contains filtered or unexported fields
}

Map is an immutable mapping of integer enum values to string names. It must be instantiated with NewMap.

func NewMap

func NewMap[Enum IntegerEnum](enumNames map[Enum]string) Map[Enum]

NewMap transforms the given enum-value-to-name map into a more efficient representation, which also provides utility methods for getting and marshaling enum names and values.

Panics if:

  • the range of integer enum keys in the map is not contiguous
  • there are duplicate names in the map

func (Map[Enum]) ContainsKey added in v0.2.0

func (enumMap Map[Enum]) ContainsKey(key Enum) bool

ContainsKey checks if the given enum key exists in the map.

func (Map[Enum]) ContainsName

func (enumMap Map[Enum]) ContainsName(name string) bool

ContainsName checks if any enum key maps to the given name.

func (Map[Enum]) GetKey added in v0.2.0

func (enumMap Map[Enum]) GetKey(name string) (key Enum, ok bool)

GetKey returns the enum key mapped to the given name, or ok=false if no mapping is found.

func (Map[Enum]) GetName

func (enumMap Map[Enum]) GetName(key Enum) (name string, ok bool)

GetName returns the mapped name for the given enum key, or ok=false if no mapping is found.

func (Map[Enum]) GetNameOrFallback

func (enumMap Map[Enum]) GetNameOrFallback(key Enum, fallback string) (name string)

GetNameOrFallback returns the mapped name for the given enum key, or the fallback if no mapping is found.

func (Map[Enum]) Keys added in v0.2.0

func (enumMap Map[Enum]) Keys() []Enum

Keys returns a slice of all enum keys in the map, sorted by their integer value. Mutating it will not affect the map.

func (Map[Enum]) MarshalToNameJSON

func (enumMap Map[Enum]) MarshalToNameJSON(key Enum) ([]byte, error)

MarshalToNameJSON marshals the given enum key to its mapped name. It errors if the key is not mapped.

func (Map[Enum]) Names

func (enumMap Map[Enum]) Names() []string

Names returns a slice of all enum names in the map, sorted by the integer value of their keys. Mutating it will not affect the map.

func (Map[Enum]) Size

func (enumMap Map[Enum]) Size() int

Size returns the number of enum-to-name entries in the map.

func (Map[Enum]) String

func (enumMap Map[Enum]) String() string

String returns a string representation of the map, mapping integer enum keys to their names.

func (Map[Enum]) UnmarshalFromNameJSON

func (enumMap Map[Enum]) UnmarshalFromNameJSON(nameJSON []byte, dest *Enum) error

UnmarshalFromNameJSON unmarshals the given enum name JSON to string, and sets dest to the enum key mapped to the name. It errors if string unmarshaling fails, or if the unmarshaled enum name is not mapped.

Jump to

Keyboard shortcuts

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