Learn how to use the core functionality of goenums with simple examples.
Simple Enum Definition
Here’s a simple enum definition for task statuses:
package validation
type status int
//go:generate goenums status.go
const (
unknown status = iota // invalid Unknown
pending // Pending
approved // Approved
rejected // Rejected
completed // Completed
)
This enum has a standard alias for each enum value defined in the comment.
Generate the enum implementations with the goenums tool:
$ go generate ./...
Custom String Representations
As with the above example, we can add a custom string representation to each enum value:
Standard Name Comment
type ticketStatus int
//go:generate goenums status.go
const (
unknown ticketStatus = iota // invalid Unknown
pending // Pending
approved // Approved
rejected // Rejected
completed // Completed
)
Name Comment with spaces
When using alias names that contain spaces, the double quotes are required:
package validation
type ticketStatus int
//go:generate goenums status.go
const (
unknown ticketStatus = iota // invalid "Not Found"
pending // "In Progress"
approved // "Fully Approved"
rejected // "Has Been Rejected"
completed // "Successfully Completed"
)
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 pending enum:
status, err := validation.ParseTicketStatus("In Progress")
if err != nil {
fmt.Println("error:", err)
}
status, err := validation.ParseTicketStatus("in progress")
if err != nil {
fmt.Println("error:", err)
}
status, err := validation.ParseTicketStatus("IN PROGRESS")
if err != nil {
fmt.Println("error:", err)
}
JSON, Text, Binary, YAML, and Database Storage
The generated enum type implements the:
json.Marshalerandjson.Unmarshalerinterfacessql.Scannerandsql.Valuerinterfacesencoding.BinaryMarshalerandencoding.BinaryUnmarshalerinterfacesencoding.TextMarshalerandencoding.TextUnmarshalerinterfacesyaml.Marshalerandyaml.Unmarshalerinterfaces
These interfaces allow you to use the enum type in JSON, text, binary, YAML, and database storage seamlessly.
Selecting generated interfaces
By default, goenums generates JSON, Text, YAML, SQL, and Binary interface methods. Use --interfaces when you only want a subset:
goenums --interfaces=json,sql ticket_status.go
Valid values are json, text, yaml, sql, and binary. If text is not selected, -legacy-text has no generated-code effect.
Enum accessor style
Generated enum values are exposed through a container such as TicketStatuses. The default upper style preserves the existing selector names:
TicketStatuses.PENDING_APPROVAL
For idiomatic exported Go selectors, opt in when generating:
//go:generate goenums --accessor-style=go ticket_status.go
TicketStatuses.PendingApproval
Changing styles requires updating Go call sites. It does not change aliases, parsing, serialized values, database values, numeric values, or generated filenames.
Text and JSON compatibility
MarshalText returns raw enum text by default. Use goenums -legacy-text file.go if you need the older quoted MarshalText output. JSON marshaling uses standard JSON string escaping, and JSON unmarshaling also accepts raw enum text when called directly.
Numeric Parsing Support
The generated enums support parsing from various numeric types. Numeric inputs are matched against the underlying enum constant values, not ordinal positions:
// Parse from different numeric types
status1, _ := validation.ParseTicketStatus(1) // int
status2, _ := validation.ParseTicketStatus(int32(2)) // int32
status3, _ := validation.ParseTicketStatus(3.0) // float64
status4, _ := validation.ParseTicketStatus(uint8(4)) // uint8
// All numeric types are supported: int, int8, int16, int32, int64,
// uint, uint8, uint16, uint32, uint64, float32, float64
Basic Usage After Generation
Use the generated code from the ticketStatus example above:
ticketStatus := validation.TicketStatuses.PENDING
fmt.Println(ticketStatus.String()) // "Pending"
parsed, err := validation.ParseTicketStatus("Approved")
if err != nil {
return err
}
if !parsed.IsValid() {
return fmt.Errorf("invalid ticket status")
}
type Task struct {
ID int `json:"id"`
Status validation.TicketStatus `json:"status"`
}
for status := range validation.TicketStatuses.All() {
fmt.Printf("Status: %s\n", status)
}