Generate Go enum encoding
MIT License
go install github.com/nikolaydubina/go-enum-encoding@latest
type Color struct{ c uint8 }
//go:generate go-enum-encoding -type=Color
var (
UndefinedColor = Color{} // json:""
Red = Color{1} // json:"red"
Green = Color{2} // json:"green"
Blue = Color{3} // json:"blue"
)
It also works with raw iota
enums:
type Size uint8
//go:generate go-enum-encoding -type=Size
const (
UndefinedSize Size = iota // json:""
Small // json:"small"
Large // json:"large"
XLarge // json:"xlarge"
)
@mishak87 proposed to use array instead of map for performance. Similarly, @nikolaydubina faced degradation in performance for loop based array for large enum sets (256 values) while working on fpmoney[^2] and iso4217[^3].
$ go test -bench=Benchmark -benchmem ./internal/research/map > map.bench
$ go test -bench=Benchmark -benchmem ./internal/research/inline > inline.bench
$ go test -bench=Benchmark -benchmem ./internal/research/array-loop > array-loop.bench
$ go test -bench=Benchmark -benchmem ./internal/research/array-index > array-index.bench
$ go test -bench=Benchmark -benchmem ./internal/research/uint-array > uint-array.bench
$ go test -bench=Benchmark -benchmem ./internal/research/uint-inline > uint-inline.bench
$ benchstat -split="XYZ" map.bench inline.bench array-loop.bench array-index.bench uint-array.bench uint-inline.bench
name \ time/op map.bench inline.bench array-loop.bench array-index.bench uint-array.bench uint-inline.bench
MarshalText_Color-16 22.3ns ± 0% 5.3ns ± 0% 7.5ns ± 0% 2.2ns ± 0% 1.9ns ± 0% 5.0ns ± 0%
UnmarshalText_Color-16 11.9ns ± 0% 5.7ns ± 0% 14.5ns ± 0% 11.8ns ± 0% 14.3ns ± 0% 5.7ns ± 0%
name \ alloc/op map.bench inline.bench array-loop.bench array-index.bench uint-array.bench uint-inline.bench
MarshalText_Color-16 0.00B 0.00B 0.00B 0.00B 0.00B 0.00B
UnmarshalText_Color-16 0.00B 0.00B 0.00B 0.00B 0.00B 0.00B
name \ allocs/op map.bench inline.bench array-loop.bench array-index.bench uint-array.bench uint-inline.bench
MarshalText_Color-16 0.00 0.00 0.00 0.00 0.00 0.00
UnmarshalText_Color-16 0.00 0.00 0.00 0.00 0.00 0.00
String() string
method is very similar to encoding, howver it does not return error and returns string
instead of []byte
.
To avoid malloc and convenience, stringer option is added to generate it accompanied with tests and benchmarks.
First used in tailscale.
Some enums are encoded directly as underlying basic type, however they have dual custom use through String() string
methods and alike.
To assist safe migration, custom encode and decode method names are added.
First used in tailscale.
[^1]: Comparison to other enums methods: http://github.com/nikolaydubina/go-enum-example [^2]: iso4217 enums performance loop vs map: https://github.com/ferdypruis/iso4217/issues/4 [^3]: fpmoney: https://github.com/nikolaydubina/fpmoney?tab=readme-ov-file#appendix-a-jsonunmarshal-optimizations