SkillAgentSearch skills...

Goenums

Type Safe Enum generator for Go

Install / Use

/learn @zarldev/Goenums
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

goenums

License: MIT build Go Report Card

goenums addresses Go's lack of native enum support by generating comprehensive, type-safe enum implementations from simple constant declarations. Transform basic iota based constants into feature-rich enums with string conversion, validation, JSON handling, database integration, and more.

Installation

go install github.com/zarldev/goenums@latest

Documentation

Documentation is available at https://zarldev.github.io/goenums.

Table of Contents

Key Features

  • Type Safety: Wrapper types prevent accidental misuse of enum values
  • String Conversion: Automatic string representation and parsing
  • JSON Support: Built-in marshaling and unmarshaling
  • YAML Support: Built-in YAML marshaling and unmarshaling
  • Database Integration: SQL Scanner and Valuer implementations
  • Text/Binary Marshaling: Support for encoding.TextMarshaler/TextUnmarshaler and BinaryMarshaler/BinaryUnmarshaler
  • Numeric Parsing: Parse enums from various numeric types (int, float, etc.)
  • Validation: Methods to check for valid enum values
  • Iteration: Modern Go 1.23+ iteration support with legacy fallback
  • Extensibility: Add custom fields to enums via comments
  • Exhaustive Handling: Helper functions to ensure you handle all enum values
  • Alias Support: Alternative enum names via comment syntax
  • Zero Dependencies: Completely dependency-free, using only the Go standard library

Usage

$ goenums -h
   ____ _____  ___  ____  __  ______ ___  _____
  / __ '/ __ \/ _ \/ __ \/ / / / __ '__ \/ ___/
 / /_/ / /_/ /  __/ / / / /_/ / / / / / (__  ) 
 \__, /\____/\___/_/ /_/\__,_/_/ /_/ /_/____/  
/____/
Usage: goenums [options] file.go[,file2.go,...]
Options:
  -c
  -constraints
    	Specify whether to generate the float and integer constraints or import 'golang.org/x/exp/constraints' (default: false - imports)
  -f
  -failfast
    	Enable failfast mode - fail on generation of invalid enum while parsing (default: false)
  -h
  -help
    	Print help information
  -i
  -insensitive
    	Generate case insensitive string parsing (default: false)
  -l
  -legacy
    	Generate legacy code without Go 1.23+ iterator support (default: false)
  -o string
  -output string
    	Specify the output format (default: go)
  -v
  -version
    	Print version information
  -vv
  -verbose
    	Enable verbose mode - prints out the generated code (default: false)

Features Expanded

Custom String Representations

Handle custom string representations defined in the comments of each enum. Support for enum strings with spaces is supported by adding the alternative name in double quotes:

Standard Name Comment

When the Alternative name does not contain spaces there is no need to add the double quotes.

type status int

//go:generate goenums -f -c status.go
const (
    unknown   status = iota // invalid UNKNOWN
    failed                  // FAILED
    passed                  // PASSED
    skipped                 // SKIPPED
    scheduled               // SCHEDULED
    running                 // RUNNING
    booked                  // BOOKED
)

Name Comment with spaces

When using Alternative names that contain spaces, the double quotes are required.

type order int

//go:generate goenums status.go
const (
	created     order = iota // "CREATED"
	approved                 // "APPROVED"
	processing               // "PROCESSING"
	readyToShip              // "READY TO SHIP"
	shipped                  // "SHIPPED TO CUSTOMER"
	delivered                // "DELIVERED TO CUSTOMER"
	cancelled                // "CANCELLED BY CUSTOMER"
	refunded                 // "REFUNDED TO CUSTOMER"
	closed                   // "CLOSED"
)

Extended Enum Types with Custom Fields

Add custom fields to your enums with type comments:

// Define fields in the type comment using one of three formats:
// 1. Space-separated: "Field Type,AnotherField Type"
// 2. Brackets: "Field[Type],AnotherField[Type]"
// 3. Parentheses: "Field(Type),AnotherField(Type)"

type planet int // Gravity float64,RadiusKm float64,MassKg float64,OrbitKm float64,OrbitDays float64,SurfacePressureBars float64,Moons int,Rings bool

//go:generate goenums planets.go
const (
	mercury planet = iota // Mercury 0.378,2439.7,3.3e23,57910000,88,0.0000000001,0,false
	venus                     // Venus 0.907,6051.8,4.87e24,108200000,225,92,0,false
	earth                     // Earth 1,6378.1,5.97e24,149600000,365,1,1,false
	mars                      // Mars 0.377,3389.5,6.42e23,227900000,687,0.01,2,false
	jupiter                   // Jupiter 2.36,69911,1.90e27,778600000,4333,20,4,true
	saturn                    // Saturn 0.916,58232,5.68e26,1433500000,10759,1,7,true
	uranus                    // Uranus 0.889,25362,8.68e25,2872500000,30687,1.3,13,true
	neptune                   // Neptune 1.12,24622,1.02e26,4495100000,60190,1.5,2,true
)

Then we can use the extended enum type:

earthWeight := 100.0
fmt.Printf("Weight on %s: %.2f kg\n", 
    solarsystem.Planets.MARS, 
    earthWeight * solarsystem.Planets.MARS.Gravity)

Case Insensitive String Parsing

Use the -i flag to enable case insensitive string parsing:

//go:generate goenums -i status.go

// Generated code will parse case insensitive strings. All
// of the below will validate and produce the 'PASSED' enum
status, err := validation.ParseStatus("PASSED")
if err != nil {
    fmt.Println("error:", err)
}
status, err := validation.ParseStatus("passed")
if err != nil {
    fmt.Println("error:", err)
}
status, err := validation.ParseStatus("Passed")
if err != nil {
    fmt.Println("error:", err)
}

JSON, Text, Binary, YAML, and Database Storage

The generated enum type also implements several common interfaces:

  • json.Marshaler and json.Unmarshaler
  • sql.Scanner and sql.Valuer
  • encoding.TextMarshaler and encoding.TextUnmarshaler
  • encoding.BinaryMarshaler and encoding.BinaryUnmarshaler

These interfaces are used to handle parsing for JSON, Text, Binary, and Database storage using the common standard library packages. As there is no standard library support for YAML, the generated YAML marshaling and unmarshaling methods are based on the * yaml.Marshaler and yaml.Unmarshaler interfaces from the goccy/go-yaml module.

Here is an example of the generated handling code:

// MarshalJSON implements the json.Marshaler interface for Status.
// It returns the JSON representation of the enum value as a byte slice.
func (p Status) MarshalJSON() ([]byte, error) {
	return []byte("\"" + p.String() + "\""), nil
}

// UnmarshalJSON implements the json.Unmarshaler interface for Status.
// It parses the JSON representation of the enum value from the byte slice.
// It returns an error if the input is not a valid JSON representation.
func (p *Status) UnmarshalJSON(b []byte) error {
	b = bytes.Trim(bytes.Trim(b, "\""), "\"")
	newp, err := ParseStatus(b)
	if err != nil {
		return err
	}
	*p = newp
	return nil
}

// MarshalText implements the encoding.TextMarshaler interface for Status.
// It returns the string representation of the enum value as a byte slice
func (p Status) MarshalText() ([]byte, error) {
	return []byte("\"" + p.String() + "\""), nil
}

// UnmarshalText implements the encoding.TextUnmarshaler interface for Status.
// It parses the string representation of the enum value from the byte slice.
// It returns an error if the byte slice does not contain a valid enum value.
func (p *Status) UnmarshalText(b []byte) error {
	newp, err := ParseStatus(b)
	if err != nil {
		return err
	}
	*p = newp
	return nil
}

// Scan implements the database/sql.Scanner interface for Status.
// It parses the string representation of the enum value from the database row.
// It returns an error if the row does not contain a valid enum value.
func (p *Status) Scan(value any) error {
	newp, err := ParseStatus(value)
	if err != nil {
		return err
	}
	*p = newp
	return nil
}

// Value implements the database/sql/driver.Valuer interface for Status.
// It returns the string representation of the enum value.
func (p Status) Value() (driver.Value, error) {
	return p.String(), nil
}

// MarshalBinary implements the encoding.BinaryMarshaler interface for Status.
// It returns the binary representation of the enum value as a byte slice.
func (p Status) MarshalBinary() ([]byte, error) {
	return []byte("\"" + p.String() + "\""), nil
}

// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface for Status.
// It parse
View on GitHub
GitHub Stars370
CategoryDevelopment
Updated20d ago
Forks13

Languages

Go

Security Score

95/100

Audited on Mar 12, 2026

No findings