A struct based golang enum package that handles stringifying, marshalling, and unmarshalling.
go get github.com/eddieowens/go-enum
The following creates an enum of currency codes and uses them on the Money
struct
type CurrencyCodes struct {
enum.Enum
USD enum.Const
EUR enum.Const
CAD enum.Const
Custom enum.Const `enum:"CUSTOM"`
}
type Money struct {
CurrencyCode CurrencyCode `json:"currency_code"`
Amount int `json:"amount"`
}
To create a currency code you must use one of the following functions
// Instantiate with a provided value and panic if the value is not valid
cc := enum.MustConstruct(new(CurrencyCodes), enum.Const("USD")).(*CurrencyCodes)
// Instantiate with a provided value and return an error if the value is not valid
cc, err := enum.Construct(new(CurrencyCodes), enum.Const("USD")).(*CurrencyCodes)
// Create a new enum with no value set
cc := enum.New(new(CurrencyCodes)).(*CurrencyCodes)
To get the value and compare it with another
cc.Get() == cc.USD
To set the value, use any of the following
// If the value is invalid, an error is returned
err := cc.Set(cc.CAD)
// If the value is invalid, a panic occurs
cc.MustSet(cc.CAD)
// Set the value to a `Const` type
cc.Set(Const("EUR"))
func main() {
// Create without a value
cc := enum.New(new(CurrencyCodes)).(*CurrencyCodes)
// Instantiate with a provided value then get it
cc = enum.MustConstruct(new(CurrencyCodes), enum.Const("USD")).(*CurrencyCodes)
fmt.Println(cc.USD == cc.Get()) // Prints true
// Set valid value
cc.MustSet(cc.Custom)
// Set invalid value
err := cc.Set(Const("Random"))
fmt.Println(err.Error()) // Prints "Random is not a valid enum"
// Get all possible enums
consts := cc.GetAll()
for _, c := range consts{
...
}
// Marshal
m := Money{
CurrencyCode: *cc,
Amount: 5,
}
out, err := json.Marshal(c)
fmt.Println(string(out)) // Prints "{"currency_code":"USD","amount":5}"
// Unmarshal valid value
var money Money
json.Unmarshal([]byte("{\"currency_code\":\"USD\",\"amount\":5}"), &money)
enum.Validate(&money.CurrencyCode) // <-- Must be run after unmarshal
fmt.Println(money) // Prints "{USD 5}"
// Unmarshal invalid value
var money Money
json.Unmarshal([]byte("{\"currency_code\":\"Random\",\"amount\":5}"), &money)
err := enum.Validate(&money.CurrencyCode) // <-- Must be run after unmarshal
fmt.Println(err.Error()) // Prints "Random is not a valid enum"
// Stringify
cc = enum.MustConstruct(new(CurrencyCodes), enum.Const("CUSTOM")).(*CurrencyCodes)
fmt.Println(cc) // Prints "CUSTOM"
}
All unmarshalling needs to be followed with a call to enum.Validate(...)
. If it is not
the value placed on the enum may not be valid and the enum will not function as expected.
The name of the field on the struct will be the default value for the enum const.
For example with CurrencyCodes.USD
the Const
value is "USD". In order to customize
this value, add the tag enum:"<NAME>"
like in CurrencyCodes.Custom