enums

package
v0.3.7 Latest Latest
Warning

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

Go to latest
Published: Dec 10, 2024 License: BSD-3-Clause Imports: 7 Imported by: 55

README

Enums in Go

Enums provides utilities for creating and using enumerated types in Go. There are two main parts of enums: command enumgen and package enums. Most end-users should only have to interact with enumgen.

Enumgen

Enumgen generates code for enumerated types that aids in various operations with them, including printing, setting, and marshalling. Enumgen is based on dmarkham/enumer and stringer. To install enumgen, run:

go install cogentcore.org/core/enums/cmd/enumgen@latest

Then, in any package you have enums, add one go:generate line at the top of a file (only one per package):

package mypackage

//go:generate enumgen

...

Enum types are simply defined as any other Go type would be, just with a comment directive after it. Standard enum types can be defined as any signed or unsigned integer type, although int32 is preferred because enum types could need to be big but never need to be giant. Bit flag enum types must be int64; see Bit flag enums for why.

After the type declaration of each enum, add one of the following two comment directives:

  • //enums:enum for standard enums
  • //enums:bitflag for bit flag enums (see Bit flag enums for more information)

Then, declare your enum values in a constant block using iota. The constant values can be unsequential, offset, and/or negative (although bit flags can not be negative), but most enums are typically none of those. Also, you can declare aliases for values. For example:

package mypackage

//go:generate enumgen

type MyEnum int32 //enums:enum

const (
    Apple MyEnum = iota
    Orange
    Peach
)

type MyBitFlagEnum int64 //enums:bitflag

const (
    Enabled MyBitFlagEnum = iota
    Disabled
    Focused
    Hovered
)

type MyComplicatedEnum int16 //enums:enum

const (
    Go MyComplicatedEnum = -2 * iota + 1
    Python
    ObjectiveC
    JavaScript
    WorstProgrammingLanguage = ObjectiveC
    // alias ^
)

Any time you add, remove, or update enums, run go generate.

The behavior of enumgen can be customized in various ways through flags on either the package-level go:generate line or the enum-specific comment directive. Run enumgen -h in your terminal to learn about these flags. Here is a simple example of flag setting:

package mypackage

//go:generate enumgen -no-text -transform snake

type MyEnum uint32 //enums:enum -add-prefix fruit_ -no-line-comment -sql

const (
    Apple MyEnum = iota
    Orange
    Peach
)

Package enums

Package enums defines standard interfaces that enums satisfy.

  • Enum is satisfied by all enum types
  • EnumSetter is satisfied by all pointers to enum types
  • BitFlag is satisfied by all bit flag enum types
  • BitFlagSetter is satisfied by all pointers to bit flag enums types

Documenting enums

Enumgen captures any doc comments (not line comments) you place on enum values and exposes them through the Desc method. For example, if you have:

package mypackage

//go:generate enumgen

type Days uint8 //enums:enum

const (
	// Sunday is the first day of the week
	Sunday Days = iota
	// Monday is the second day of the week
	Monday
	// Tuesday is the third day of the week
	Tuesday
)

Then Sunday.Desc() will be Sunday is the first day of the week.

Bit flag enums

Bit flag enums are just enums that are not mutually exclusive, so you can have multiple of them specified at once. Each option/flag that can be specified occupies one bit, meaning that you should have a large type to avoid running out of space. Therefore, enumgen currently requires all bit flags to be of type int64, and there can be no more than 64 values for a bit flag enum type.

This package implements bit flag enums using enum values that specify a bit index for the flag, which is then used with bit shifting to create the actual bit mask. Thus, the enum values are just sequential integers like a normal enum, which allows the names to be looked up using a slice index, and are generally easier to read and understand as simple integers.

The generated String() and SetString() methods operate using the bit-shifted mask values and return the set of active bit names (separated by an OR pipe |) for a given value. Use BitIndexString() to get the name associated with the bit index values (which are typically only used for setting and checking flags).

Extending enums

You can define an enum as extending another enum, which allows you to inherit all of its values and then build on top of them. To do so, you must define the type of the new enum as an extension of the type of the enum you are extending. Furthermore, you must define the first value of the new enum as the N value of the enum you are extending. For example:

package mypackage

//go:generate enumgen

type Fruits int //enums:enum

const (
	Apple Fruits = iota
	Orange
	Peach
)

type Foods Fruits //enums:enum

const (
	Bread Foods = Foods(FruitsN) + iota
	Lettuce
	Cheese
)

NOTE: the N value is generated by enumgen, so you need to run go generate with the enum you are extending already declared before you declare your new enum. If you screw up this ordering and get an error or a panic when running go generate, you can temporarily comment out the new enum, run go:generate, and then add it back again and run go:generate again.

NOTE: in the rare case that you have an enum type that extends a non-enum, non-builtin type (eg: fixed.Int26_6), you need to specify the -no-extend flag in your //enums:enum comment directive to prevent errors. For example:

type MyEnum fixed.Int26_6 //enums:enum -no-extend

Documentation

Overview

Package enums provides common interfaces for enums and bit flag enums and utilities for using them

Package enums provides common interfaces for enums and bit flag enums and utilities for using them

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BitFlagString added in v0.0.8

func BitFlagString[T BitFlagConstraint](i T, values []T) string

BitFlagString returns the string representation of the given bit flag value with the given values available.

func BitFlagStringExtended added in v0.0.8

func BitFlagStringExtended[T, E BitFlagConstraint](i T, values []T, extendedValues []E) string

BitFlagStringExtended returns the string representation of the given bit flag value with the given values available, with the bit flag type extending the other given bit flag type that has the given values (extendedValues) available.

func BitIndexStringExtended added in v0.0.8

func BitIndexStringExtended[T, E BitFlagConstraint](i T, m map[T]string) string

BitIndexStringExtended returns the string representation of the given bit flag enum bit index value with the given map, with the bit flag type extending the given other bit flag type.

func Desc added in v0.0.8

func Desc[T EnumConstraint](i T, descMap map[T]string) string

Desc returns the description of the given enum value.

func DescExtended added in v0.0.8

func DescExtended[T, E EnumConstraint](i T, descMap map[T]string) string

DescExtended returns the description of the given enum value, with the enum type extending the other given enum type.

func HasFlag added in v0.0.8

func HasFlag(i *int64, f BitFlag) bool

HasFlag returns whether these bit flags have the given bit flag set.

func Scan added in v0.0.8

func Scan[T EnumSetter](i T, value any, typeName string) error

Scan loads the enum from the given SQL scanner value.

func SetFlag added in v0.0.8

func SetFlag(i *int64, on bool, f ...BitFlag)

SetFlag sets the value of the given flags in these flags to the given value.

func SetString added in v0.0.8

func SetString[T EnumConstraint](i *T, s string, valueMap map[string]T, typeName string) error

SetString sets the given enum value from its string representation, the map from enum names to values, and the name of the enum type, which is used for the error message.

func SetStringExtended added in v0.0.8

func SetStringExtended[T EnumConstraint, E EnumSetter](i *T, ie E, s string, valueMap map[string]T) error

SetStringExtended sets the given enum value from its string representation and the map from enum names to values, with the enum type extending the other given enum type. It also takes the enum value in terms of the extended enum type (ie).

func SetStringLower added in v0.0.8

func SetStringLower[T EnumConstraint](i *T, s string, valueMap map[string]T, typeName string) error

SetStringLower sets the given enum value from its string representation, the map from enum names to values, and the name of the enum type, which is used for the error message. It also tries the lowercase version of the given string if the original version fails.

func SetStringLowerExtended added in v0.0.8

func SetStringLowerExtended[T EnumConstraint, E EnumSetter](i *T, ie E, s string, valueMap map[string]T) error

SetStringLowerExtended sets the given enum value from its string representation and the map from enum names to values, with the enum type extending the other given enum type. It also takes the enum value in terms of the extended enum type (ie). It also tries the lowercase version of the given string if the original version fails.

func SetStringOr added in v0.0.8

func SetStringOr[T BitFlagConstraint, S BitFlagSetter](i S, s string, valueMap map[string]T, typeName string) error

SetStringOr sets the given bit flag value from its string representation while preserving any bit flags already set.

func SetStringOrExtended added in v0.0.8

func SetStringOrExtended[T BitFlagConstraint, S BitFlagSetter, E BitFlagSetter](i S, ie E, s string, valueMap map[string]T) error

SetStringOrExtended sets the given bit flag value from its string representation while preserving any bit flags already set, with the enum type extending the other given enum type. It also takes the enum value in terms of the extended enum type (ie).

func SetStringOrLower added in v0.0.8

func SetStringOrLower[T BitFlagConstraint, S BitFlagSetter](i S, s string, valueMap map[string]T, typeName string) error

SetStringOrLower sets the given bit flag value from its string representation while preserving any bit flags already set. It also tries the lowercase version of each flag string if the original version fails.

func SetStringOrLowerExtended added in v0.0.8

func SetStringOrLowerExtended[T BitFlagConstraint, S BitFlagSetter, E BitFlagSetter](i S, ie E, s string, valueMap map[string]T) error

SetStringOrLowerExtended sets the given bit flag value from its string representation while preserving any bit flags already set, with the enum type extending the other given enum type. It also takes the enum value in terms of the extended enum type (ie). It also tries the lowercase version of each flag string if the original version fails.

func String added in v0.0.8

func String[T EnumConstraint](i T, m map[T]string) string

String returns the string representation of the given enum value with the given map.

func StringExtended added in v0.0.8

func StringExtended[T, E EnumConstraint](i T, m map[T]string) string

StringExtended returns the string representation of the given enum value with the given map, with the enum type extending the given other enum type.

func UnmarshalText added in v0.0.8

func UnmarshalText[T EnumSetter](i T, text []byte, typeName string) error

UnmarshalText loads the enum from the given text. It logs any error instead of returning it to prevent one modified enum from tanking an entire object loading operation.

func ValuesGlobalExtended added in v0.0.8

func ValuesGlobalExtended[T, E EnumConstraint](values []T, extendedValues []E) []T

ValuesGlobalExtended returns also possible values for the given enum type that extends the other given enum type.

Types

type BitFlag

type BitFlag interface {
	Enum

	// BitIndexString returns the string
	// representation of the bit flag if
	// the bit flag is a bit index value
	// (typically an enum constant), and
	// not an actual bit flag value.
	BitIndexString() string
}

BitFlag is the interface that all bit flag enum types satisfy. Bit flag enum types support all of the operations that standard enums do, and additionally can check if they have a given bit flag. Note that HasFlag is defined on BitFlagSetter since it requires a pointer receiver for atomic operations to prevent race conditions.

type BitFlagConstraint added in v0.0.8

type BitFlagConstraint interface {
	BitFlag
	num.Integer
}

BitFlagConstraint is the generic type constraint that all bit flags satisfy.

type BitFlagSetter

type BitFlagSetter interface {
	EnumSetter
	BitFlag

	// Has returns whether these flags
	// have the given flag set.
	HasFlag(f BitFlag) bool

	// Set sets the value of the given
	// flags in these flags to the given value.
	SetFlag(on bool, f ...BitFlag)

	// SetStringOr sets the bit flag from its
	// string representation while preserving any
	// bit flags already set, and returns an
	// error if the string is invalid.
	SetStringOr(s string) error
}

BitFlagSetter is an expanded interface that all pointers to bit flag enum types satisfy. Pointers to bit flag enum types must satisfy all of the methods of EnumSetter and BitFlag, and must also be able to set a given bit flag.

type Enum

type Enum interface {
	fmt.Stringer

	// Int64 returns the enum value as an int64.
	Int64() int64

	// Desc returns the description of the enum value.
	Desc() string

	// Values returns all possible values this
	// enum type has.
	Values() []Enum
}

Enum is the interface that all enum types satisfy. Enum types must be convertable to strings and int64s, must be able to return a description of their value, must be able to report if they are valid, and must be able to return all possible enum values for their type.

func Values added in v0.0.8

func Values[T EnumConstraint](values []T) []Enum

Values returns all possible values for the given enum type.

func ValuesExtended added in v0.0.8

func ValuesExtended[T, E EnumConstraint](values []T, extendedValues []E) []Enum

ValuesExtended returns all possible values for the given enum type that extends the other given enum type.

type EnumConstraint added in v0.0.8

type EnumConstraint interface {
	Enum
	num.Integer
}

EnumConstraint is the generic type constraint that all enums satisfy.

type EnumSetter

type EnumSetter interface {
	Enum

	// SetString sets the enum value from its
	// string representation, and returns an
	// error if the string is invalid.
	SetString(s string) error

	// SetInt64 sets the enum value from an int64.
	SetInt64(i int64)
}

EnumSetter is an expanded interface that all pointers to enum types satisfy. Pointers to enum types must satisfy all of the methods of Enum, and must also be settable from strings and int64s.

Directories

Path Synopsis
cmd
enumgen
Package main provides the actual command line implementation of the enumgen library.
Package main provides the actual command line implementation of the enumgen library.
Package enumgen provides functions for generating enum methods for enum types.
Package enumgen provides functions for generating enum methods for enum types.

Jump to

Keyboard shortcuts

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