go-enum
An enum generator for go
How it works
go-enum will take a commented type declaration like this:
// ENUM(jpeg, jpg, png, tiff, gif)
type ImageType int
and generate a file with the iota definition along various optional niceties that you may need:
const (
// ImageTypeJpeg is a ImageType of type Jpeg.
ImageTypeJpeg ImageType = iota
// ImageTypeJpg is a ImageType of type Jpg.
ImageTypeJpg
// ImageTypePng is a ImageType of type Png.
ImageTypePng
// ImageTypeTiff is a ImageType of type Tiff.
ImageTypeTiff
// ImageTypeGif is a ImageType of type Gif.
ImageTypeGif
)
// String implements the Stringer interface.
func (x ImageType) String() string
// ParseImageType attempts to convert a string to a ImageType.
func ParseImageType(name string) (ImageType, error)
// MarshalText implements the text marshaller method.
func (x ImageType) MarshalText() ([]byte, error)
// UnmarshalText implements the text unmarshaller method.
func (x *ImageType) UnmarshalText(text []byte) error
MarshalTextUnmarshalText
-t
Now with string typed enums
// ENUM(pending, running, completed, failed)
type StrState string
const (
// StrStatePending is a StrState of type pending.
StrStatePending StrState = "pending"
// StrStateRunning is a StrState of type running.
StrStateRunning StrState = "running"
// StrStateCompleted is a StrState of type completed.
StrStateCompleted StrState = "completed"
// StrStateFailed is a StrState of type failed.
StrStateFailed StrState = "failed"
)
--sqlint
// swagger:enum StrState
// ENUM(pending, running, completed, failed)
type StrState string
Goal
type EnumName int
String()
Installation
You can now download a release directly from github and use that for generating your enums! (Thanks to GoReleaser)
uname -suname -m
curl -fsSL "https://github.com/abice/go-enum/releases/download/$(GO_ENUM_VERSION)/go-enum_$(uname -s)_$(uname -m)" -o go-enum
Adding it to your project
Using go generate
//go:generate go-enum --marshalgo generate ./...
Using Makefile
If you prefer makefile stuff, you can always do something like this:
STANDARD_ENUMS = ./_example/animal_enum.go \
./_example/color_enum.go
NULLABLE_ENUMS = ./_example/sql_enum.go
$(STANDARD_ENUMS): GO_ENUM_FLAGS=--nocase --marshal --names --ptr
$(NULLABLE_ENUMS): GO_ENUM_FLAGS=--nocase --marshal --names --sqlnullint --ptr
enums: $(STANDARD_ENUMS) $(NULLABLE_ENUMS)
# The generator statement for go enum files. Files that invalidate the
# enum file: source file, the binary itself, and this file (in case you want to generate with different flags)
%_enum.go: %.go $(GOENUM) Makefile
$(GOENUM) -f $*.go $(GO_ENUM_FLAGS)
Command options
go-enum --help
NAME:
go-enum - An enum generator for go
USAGE:
go-enum [global options] [arguments...]
VERSION:
example
GLOBAL OPTIONS:
--file value, -f value [ --file value, -f value ] The file(s) to generate enums. Use more than one flag for more files. [$GOFILE]
--noprefix Prevents the constants generated from having the Enum as a prefix. (default: false)
--lower Adds lowercase variants of the enum strings for lookup. (default: false)
--nocase Adds case insensitive parsing to the enumeration (forces lower flag). (default: false)
--marshal Adds text (and inherently json) marshalling functions. (default: false)
--sql Adds SQL database scan and value functions. (default: false)
--sqlint Tells the generator that a string typed enum should be stored in sql as an integer value. (default: false)
--flag Adds golang flag functions. (default: false)
--prefix value Adds a prefix with a user one. If you would like to replace the prefix, then combine this option with --noprefix.
--names Generates a 'Names() []string' function, and adds the possible enum values in the error response during parsing (default: false)
--values Generates a 'Values() []{{ENUM}}' function. (default: false)
--nocamel Removes the snake_case to CamelCase name changing (default: false)
--ptr Adds a pointer method to get a pointer from const values (default: false)
--sqlnullint Adds a Null{{ENUM}} type for marshalling a nullable int value to sql (default: false)
--sqlnullstr Adds a Null{{ENUM}} type for marshalling a nullable string value to sql. If sqlnullint is specified too, it will be Null{{ENUM}}Str (default: false)
--template value, -t value [ --template value, -t value ] Additional template file(s) to generate enums. Use more than one flag for more files. Templates will be executed in alphabetical order.
--alias value, -a value [ --alias value, -a value ] Adds or replaces aliases for a non alphanumeric value that needs to be accounted for. [Format should be "key:value,key2:value2", or specify multiple entries, or both!]
--mustparse Adds a Must version of the Parse that will panic on failure. (default: false)
--forcelower Forces a camel cased comment to generate lowercased names. (default: false)
--forceupper Forces a camel cased comment to generate uppercased names. (default: false)
--nocomments Removes auto generated comments. If you add your own comments, these will still be created. (default: false)
--buildtag value, -b value [ --buildtag value, -b value ] Adds build tags to a generated enum file.
--help, -h show help
--version, -v print the version
Syntax
ENUM()=numericValue5051, 52, 53...
Comments
//
// Commented is an enumeration of commented values
/*
ENUM(
value1 // Commented value 1
value2
value3 // Commented value 3
)
*/
type Commented int
The generated comments in code will look something like:
...
const (
// CommentedValue1 is a Commented of type Value1
// Commented value 1
CommentedValue1 Commented = iota
// CommentedValue2 is a Commented of type Value2
CommentedValue2
// CommentedValue3 is a Commented of type Value3
// Commented value 3
CommentedValue3
)
...
Example
_example
// Color is an enumeration of colors that are allowed.
/* ENUM(
Black, White, Red
Green = 33 // Green starts with 33
*/
// Blue
// grey=
// yellow
// blue-green
// red-orange
// yellow_green
// red-orange-blue
// )
type Color int32
The generated code will look something like:
// Code generated by go-enum DO NOT EDIT.
// Version: example
// Revision: example
// Build Date: example
// Built By: example
package example
import (
"fmt"
"strings"
)
const (
// ColorBlack is a Color of type Black.
ColorBlack Color = iota
// ColorWhite is a Color of type White.
ColorWhite
// ColorRed is a Color of type Red.
ColorRed
// ColorGreen is a Color of type Green.
// Green starts with 33
ColorGreen Color = iota + 30
// ColorBlue is a Color of type Blue.
ColorBlue
// ColorGrey is a Color of type Grey.
ColorGrey
// ColorYellow is a Color of type Yellow.
ColorYellow
// ColorBlueGreen is a Color of type Blue-Green.
ColorBlueGreen
// ColorRedOrange is a Color of type Red-Orange.
ColorRedOrange
// ColorYellowGreen is a Color of type Yellow_green.
ColorYellowGreen
// ColorRedOrangeBlue is a Color of type Red-Orange-Blue.
ColorRedOrangeBlue
)
const _ColorName = "BlackWhiteRedGreenBluegreyyellowblue-greenred-orangeyellow_greenred-orange-blue"
var _ColorMap = map[Color]string{
ColorBlack: _ColorName[0:5],
ColorWhite: _ColorName[5:10],
ColorRed: _ColorName[10:13],
ColorGreen: _ColorName[13:18],
ColorBlue: _ColorName[18:22],
ColorGrey: _ColorName[22:26],
ColorYellow: _ColorName[26:32],
ColorBlueGreen: _ColorName[32:42],
ColorRedOrange: _ColorName[42:52],
ColorYellowGreen: _ColorName[52:64],
ColorRedOrangeBlue: _ColorName[64:79],
}
// String implements the Stringer interface.
func (x Color) String() string {
if str, ok := _ColorMap[x]; ok {
return str
}
return fmt.Sprintf("Color(%d)", x)
}
var _ColorValue = map[string]Color{
_ColorName[0:5]: ColorBlack,
strings.ToLower(_ColorName[0:5]): ColorBlack,
_ColorName[5:10]: ColorWhite,
strings.ToLower(_ColorName[5:10]): ColorWhite,
_ColorName[10:13]: ColorRed,
strings.ToLower(_ColorName[10:13]): ColorRed,
_ColorName[13:18]: ColorGreen,
strings.ToLower(_ColorName[13:18]): ColorGreen,
_ColorName[18:22]: ColorBlue,
strings.ToLower(_ColorName[18:22]): ColorBlue,
_ColorName[22:26]: ColorGrey,
strings.ToLower(_ColorName[22:26]): ColorGrey,
_ColorName[26:32]: ColorYellow,
strings.ToLower(_ColorName[26:32]): ColorYellow,
_ColorName[32:42]: ColorBlueGreen,
strings.ToLower(_ColorName[32:42]): ColorBlueGreen,
_ColorName[42:52]: ColorRedOrange,
strings.ToLower(_ColorName[42:52]): ColorRedOrange,
_ColorName[52:64]: ColorYellowGreen,
strings.ToLower(_ColorName[52:64]): ColorYellowGreen,
_ColorName[64:79]: ColorRedOrangeBlue,
strings.ToLower(_ColorName[64:79]): ColorRedOrangeBlue,
}
// ParseColor attempts to convert a string to a Color
func ParseColor(name string) (Color, error) {
if x, ok := _ColorValue[name]; ok {
return x, nil
}
return Color(0), fmt.Errorf("%s is not a valid Color", name)
}
func (x Color) Ptr() *Color {
return &x
}
// MarshalText implements the text marshaller method
func (x Color) MarshalText() ([]byte, error) {
return []byte(x.String()), nil
}
// UnmarshalText implements the text unmarshaller method
func (x *Color) UnmarshalText(text []byte) error {
name := string(text)
tmp, err := ParseColor(name)
if err != nil {
return err
}
*x = tmp
return nil
}