modulepackage
0.0.2
Repository: https://github.com/daichitakahashi/go-enum.git
Documentation: pkg.go.dev
# README
go-enum
Idea from following video.
列挙型の作り方を再考する - Go Conference 2023 Online
This package provides support for defining Visitor
and implementing Accept()
methods.
Usage
Examples here.
- Prepare enum interface and member types.
package fruits
import "github.com/daichitakahashi/go-enum"
type (
// enum interface
Fruits interface{}
// member types
Apple enum.MemberOf[Fruits]
Orange enum.MemberOf[Fruits]
Grape enum.MemberOf[Fruits]
)
- Run following command.
$ go run github.com/daichitakahashi/go-enum/cmd/enumgen
- Following code is generated with the file name
enum.gen.go
(file name is configurable).
// Code generated by enumgen. DO NOT EDIT.
package fruits
type (
FruitsVisitor interface {
VisitApple(e Apple)
VisitOrange(e Orange)
VisitGrape(e Grape)
}
FruitsEnum interface {
Accept(v FruitsVisitor)
}
)
func (e Apple) Accept(v FruitsVisitor) {
v.VisitApple(e)
}
func (e Orange) Accept(v FruitsVisitor) {
v.VisitOrange(e)
}
func (e Grape) Accept(v FruitsVisitor) {
v.VisitGrape(e)
}
var _ = []FruitsEnum{Apple{}, Orange{}, Grape{}}
- Optional: Embed generated
FruitsEnum
type inFruits
type.
type (
// enum interface
Fruits interface{
FruitsEnum
}
...
- Implement your visitor type!
Options for enumgen
option | description | default value |
---|---|---|
--wd | working directory | . |
--out | output file name | enum.gen.go |
--visitor | customize Visitor type & method names | *:*Visitor:Visit* |
--accept | customize Accept method name | *:Accept |
--visitor
option
The value of --visitor
option consists of three parts with the delimiter ":".
- The target type name(enum interface) of customization.
Pattern match using*
is allowed. - The visitor type name pattern.
If the pattern contains*
, it will replaced with the target type name. - The visit method name pattern.
If the pattern contains*
, it will replaced with the member type name.
--accept
option
The value of --accept
option consists of two parts with the delimiter ":"
- The target type name(enum interface) of customization.
Pattern match using*
is allowed. - The accept method name pattern.
If the pattern contains*
, it will replaced with the target type name.
--visitor
and --accept
options can be used multiple times.
Example: use enumgen for domain events.
package event
import (
"time"
"github.com/daichitakahashi/go-enum"
)
//go:generate go run github.com/daichitakahashi/go-enum/cmd/enumgen@latest --visitor="Event:EventHandler:On*" --accept="Event:Emit"
type (
Event interface {
ID() string
}
OrderPlaced struct {
enum.MemberOf[Event]
Items []string
}
PaymentReceived struct {
enum.MemberOf[Event]
Amount int
}
ItemShipped struct {
enum.MemberOf[Event]
ShippedAt time.Time
}
)
// ID implements Event.
func (OrderPlaced) ID() string {
return "orderPlaced"
}
// ID implements Event.
func (PaymentReceived) ID() string {
return "paymentReceived"
}
// ID implements Event.
func (ItemShipped) ID() string {
return "itemShipped"
}
var (
_ Event = OrderPlaced{}
_ Event = PaymentReceived{}
_ Event = ItemShipped{}
)
go generated:
// Code generated by enumgen. DO NOT EDIT.
package event
type (
EventHandler interface {
OnOrderPlaced(e OrderPlaced)
OnPaymentReceived(e PaymentReceived)
OnItemShipped(e ItemShipped)
}
EventEnum interface {
Emit(v EventHandler)
}
)
func (e OrderPlaced) Emit(v EventHandler) {
v.OnOrderPlaced(e)
}
func (e PaymentReceived) Emit(v EventHandler) {
v.OnPaymentReceived(e)
}
func (e ItemShipped) Emit(v EventHandler) {
v.OnItemShipped(e)
}
var _ = []EventEnum{OrderPlaced{}, PaymentReceived{}, ItemShipped{}}
# Interfaces
VisitorReturns specifies return type of visitor on enum identifier.