enumer/README.md

118 lines
4.7 KiB
Markdown
Raw Normal View History

2017-02-01 11:49:25 +03:00
# Enumer
2016-01-21 13:49:12 +03:00
Enumer is a tool to generate Go code that adds useful methods to Go enums (constants with a specific type).
It started as a fork of [Rob Pikes Stringer tool](https://godoc.org/golang.org/x/tools/cmd/stringer).
2015-12-29 16:27:33 +03:00
2017-02-01 11:49:25 +03:00
## Generated functions and methods
2016-05-21 15:34:12 +03:00
When Enumer is applied to a type, it will generate:
* A method `String()` that returns the string representation of the enum value. This makes the enum conform
the `Stringer` interface, so whenever you print an enum value, you'll get the string name instead of a number.
2016-12-20 15:57:15 +03:00
* A function `<Type>String(s string)` to get the enum value from its string representation. This is useful
when you need to read enum values from command line arguments, from a configuration file, or
from a REST API request... In short, from those places where using the real enum value (an integer) would
be almost meaningless or hard to trace or use by a human.
2016-12-20 15:57:15 +03:00
* When the flag `json` is provided, two additional methods will be generated, `MarshalJSON()` and `UnmarshalJSON()`. These make
the enum conform to the `json.Marshaler` and `json.Unmarshaler` interfaces. Very useful to use it in JSON APIs.
* When the flag `yaml` is provided, two additional methods will be generated, `MarshalYAML()` and `UnmarshalYAML()`. These make
the enum conform to the `gopkg.in/yaml.v2.Marshaler` and `gopkg.in/yaml.v2.Unmarshaler` interfaces.
2016-10-26 19:12:50 +03:00
* When the flag `sql` is provided, the methods for implementing the Scanner and Valuer interfaces will be also generated.
2016-10-26 19:12:25 +03:00
Useful when storing the enum in a database.
2015-12-31 17:36:39 +03:00
For example, if we have an enum type called `Pill`,
```go
2015-12-31 17:36:39 +03:00
type Pill int
2015-12-29 16:27:33 +03:00
2015-12-31 17:36:39 +03:00
const (
Placebo Pill = iota
Aspirin
Ibuprofen
Paracetamol
Acetaminophen = Paracetamol
)
```
2016-05-21 15:34:12 +03:00
executing `enumer -type=Pill -json` will generate a new file with four methods:
```go
2015-12-29 16:27:33 +03:00
func (i Pill) String() string {
//...
}
func PillString(s string) (Pill, error) {
//...
}
func (i Pill) MarshalJSON() ([]byte, error) {
//...
}
func (i *Pill) UnmarshalJSON(data []byte) error {
//...
}
2015-12-29 16:27:33 +03:00
```
2015-12-31 17:36:39 +03:00
From now on, we can:
```go
2015-12-31 17:36:39 +03:00
// Convert any Pill value to string
var aspirinString string = Aspirin.String()
// (or use it in any place where a Stringer is accepted)
fmt.Println("I need ", Paracetamol) // Will print "I need Paracetamol"
// Convert a string with the enum name to the corresponding enum value
pill, err := PillString("Ibuprofen")
if err != nil {
fmt.Println("Unrecognized pill: ", err)
return
}
// Now pill == Ibuprofen
2016-01-21 02:15:57 +03:00
// Marshal/unmarshal to/from json strings, either directly or automatically when
// the enum is a field of a struct
pillJSON := Aspirin.MarshalJSON()
// Now pillJSON == `"Aspirin"`
2015-12-31 17:36:39 +03:00
```
The generated code is exactly the same as the Stringer tool plus the mentioned additions, so you can use
2015-12-31 17:36:39 +03:00
**Enumer** where you are already using **Stringer** without any code change.
2015-12-29 16:27:33 +03:00
2017-02-09 14:02:18 +03:00
## Transforming the string representation of the enum value
2017-02-01 11:49:25 +03:00
2017-02-09 14:02:18 +03:00
By default, Enumer uses the same name of the enum value for generating the string representation (usually CamelCase in Go).
2017-02-01 11:49:25 +03:00
```go
type MyType int
...
name := MyTypeValue.String() // name => "MyTypeValue"
```
2017-02-09 14:02:18 +03:00
Sometimes you need to use some other string representation format than CamelCase (i.e. in JSON).
2017-11-03 00:02:53 +03:00
2017-02-09 14:02:18 +03:00
To transform it from CamelCase to snake_case or kebab-case, you can use the `transform` flag.
2017-02-01 11:49:25 +03:00
2017-02-09 14:02:18 +03:00
For example, the command `enumer -type=MyType -json -transform=snake` would generate the following string representation:
2017-02-01 11:49:25 +03:00
```go
name := MyTypeValue.String() // name => "my_type_value"
```
2017-11-03 00:02:53 +03:00
**Note**: The transformation only works form CamelCase to snake_case or kebab-case, not the other way around.
2017-02-01 11:49:25 +03:00
2015-12-31 17:36:39 +03:00
## How to use
The usage of Enumer is the same as Stringer, so you can refer to the [Stringer docs](https://godoc.org/golang.org/x/tools/cmd/stringer)
for more information.
2016-01-21 02:15:57 +03:00
2016-12-20 15:57:15 +03:00
There are three flags added: `json`, `yaml` and `sql`. If the json flag is set to true (i.e. `enumer -type=Pill -json`),
the JSON related methods will be generated. Similarly if the yaml flag is set to true,
the YAML related methods will be generated. And if the sql flag is set to true, the Scanner and Valuer interface will
2016-02-07 00:46:59 +03:00
be implemented to seamlessly use the enum in a database model.
For enum string representation transformation the `transform` and `trimprefix` flags
2017-04-10 21:37:23 +03:00
were added (i.e. `enumer -type=MyType -json -transform=snake`).
Possible transform values are `snake` and `kebab` for transformation to snake_case and kebab-case accordingly.
2017-02-01 11:49:25 +03:00
The default value for `transform` flag is `noop` which means no transformation will be performed.
2018-02-06 15:17:13 +03:00
If a prefix is provided via the `trimprefix` flag, it will be trimmed from the start of each name (before
2017-04-10 21:37:23 +03:00
it is transformed). If a name doesn't have the prefix it will be passed unchanged.
2016-01-21 02:18:14 +03:00
## Inspiring projects
* [Stringer](https://godoc.org/golang.org/x/tools/cmd/stringer)
* [jsonenums](https://github.com/campoy/jsonenums)