All Projects → dmarkham → enumer

dmarkham / enumer

Licence: other
A Go tool to auto generate methods for your enums

Programming Languages

go
31211 projects - #10 most used programming language
Makefile
30231 projects

Projects that are alternatives of or similar to enumer

Kodgen
C++17 parser and code generator
Stars: ✭ 19 (-88.62%)
Mutual labels:  codegenerator, code-generation, codegeneration
codespawn
Code generator written in Rust
Stars: ✭ 34 (-79.64%)
Mutual labels:  codegenerator, code-generation, codegeneration
CodegenCS
C# Toolkit for Code Generation (T4 alternative!)
Stars: ✭ 119 (-28.74%)
Mutual labels:  codegenerator, codegeneration
gonstructor
A command-line tool to generate a constructor for the struct.
Stars: ✭ 55 (-67.07%)
Mutual labels:  code-generation
mr.boilerplate
Online app to generate Scala boilerplate
Stars: ✭ 32 (-80.84%)
Mutual labels:  code-generation
php-test-generator
Generate test cases for existing PHP files
Stars: ✭ 47 (-71.86%)
Mutual labels:  codegenerator
EMF
Extended Mechanics & Flavor
Stars: ✭ 33 (-80.24%)
Mutual labels:  code-generation
code-fold
Write the pattern, then let your code write itself.
Stars: ✭ 13 (-92.22%)
Mutual labels:  code-generation
DataTier.Net
DataTier.Net is an Entity Framework alternative that makes it simple to create stored procedure powered data tiers.
Stars: ✭ 18 (-89.22%)
Mutual labels:  codegeneration
LstGen
Code-Generator für die Lohnsteuerberechnung aus PAP XML
Stars: ✭ 19 (-88.62%)
Mutual labels:  code-generation
openvalidation
Compose validation rules in the language you use every day, openVALIDATION handles code creation for you.
Stars: ✭ 62 (-62.87%)
Mutual labels:  code-generation
LinqToXsdCore
LinqToXsd ported to .NET Core (targets .NET Standard 2 for generated code and .NET Core 3.1, .NET 5+ 6 for the code generator CLI tool).
Stars: ✭ 23 (-86.23%)
Mutual labels:  code-generation
Java
"Always choose a lazy person to get the job done. A lazy person will always find the easy way out."
Stars: ✭ 16 (-90.42%)
Mutual labels:  enums
Rosalina
Rosalina is a code generation tool for Unity's UI documents. It generates C# code-behind script based on a UXML template.
Stars: ✭ 57 (-65.87%)
Mutual labels:  code-generation
pystella
A code generator for grid-based PDE solving on CPUs and GPUs
Stars: ✭ 18 (-89.22%)
Mutual labels:  code-generation
eaf-linter
🤪 A linter, prettier, and test suite that does everything as-simple-as-possible.
Stars: ✭ 17 (-89.82%)
Mutual labels:  code-generation
jeta
brooth.github.io/jeta
Stars: ✭ 21 (-87.43%)
Mutual labels:  code-generation
create-graphql-app
Cli tool for bootstrapping serverless GraphQL api
Stars: ✭ 28 (-83.23%)
Mutual labels:  code-generation
damascus
⚔️ CRUD boilerplate generator for Liferay DXP
Stars: ✭ 51 (-69.46%)
Mutual labels:  codegenerator
goprotoc
Library for writing protoc plugins in Go; also includes a pure-Go protoc replacement
Stars: ✭ 73 (-56.29%)
Mutual labels:  codegeneration

Enumer GoDoc Go Report Card GitHub ReleaseBuild Status

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 Pike’s Stringer tool maintained by Álvaro López Espinosa. This was again forked here as (https://github.com/dmarkham/enumer) picking up where Álvaro left off.

$ ./enumer --help
Enumer is a tool to generate Go code that adds useful methods to Go enums (constants with a specific type).
Usage of ./enumer:
        Enumer [flags] -type T [directory]
        Enumer [flags] -type T files... # Must be a single package
For more information, see:
        http://godoc.org/github.com/dmarkham/enumer
Flags:
  -addprefix string
        transform each item name by adding a prefix. Default: ""
  -comment value
        comments to include in generated code, can repeat. Default: ""
  -gqlgen
        if true, GraphQL marshaling methods for gqlgen will be generated. Default: false
  -json
        if true, json marshaling methods will be generated. Default: false
  -linecomment
        use line comment text as printed text when present
  -output string
        output file name; default srcdir/<type>_string.go
  -sql
        if true, the Scanner and Valuer interface will be implemented.
  -text
        if true, text marshaling methods will be generated. Default: false
  -transform string
        enum item name transformation method. Default: noop (default "noop")
  -trimprefix string
        transform each item name by removing a prefix. Default: ""
  -type string
        comma-separated list of type names; must be set
  -yaml
        if true, yaml marshaling methods will be generated. Default: false

Generated functions and methods

When Enumer is applied to a type, it will generate:

  • The following basic methods/functions:

    • Method String(): 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.
    • Function <Type>String(s string): returns 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. s string is Case Insensitive.
    • Function <Type>Values(): returns a slice with all the values of the enum
    • Function <Type>Strings(): returns a slice with all the Strings of the enum
    • Method IsA<Type>(): returns true only if the current value is among the values of the enum. Useful for validations.
  • 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 text is provided, two additional methods will be generated, MarshalText() and UnmarshalText(). These make the enum conform to the encoding.TextMarshaler and encoding.TextUnmarshaler interfaces. Note: If you use your enum values as keys in a map and you encode the map as JSON, you need this flag set to true to properly convert the map keys to json (strings). If not, the numeric values will be used instead

  • 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.

  • When the flag sql is provided, the methods for implementing the Scanner and Valuer interfaces. Useful when storing the enum in a database.

For example, if we have an enum type called Pill,

type Pill int

const (
	Placebo Pill = iota
	Aspirin
	Ibuprofen
	Paracetamol
	Acetaminophen = Paracetamol
)

executing enumer -type=Pill -json will generate a new file with four basic methods and two extra for JSON:

func (i Pill) String() string {
	//...
}

func PillString(s string) (Pill, error) {
	//...
}

func PillValues() []Pill {
	//...
}

func PillStrings() []string {
	//...
}

func (i Pill) IsAPill() bool {
	//...
}

func (i Pill) MarshalJSON() ([]byte, error) {
	//...
}

func (i *Pill) UnmarshalJSON(data []byte) error {
	//...
}

From now on, we can:

// 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") // "ibuprofen" will also work.
if err != nil {
    fmt.Println("Unrecognized pill: ", err)
    return
}
// Now pill == Ibuprofen

// Get all the values of the string
allPills := PillValues()
fmt.Println(allPills) // Will print [Placebo Aspirin Ibuprofen Paracetamol]

// Check if a value belongs to the Pill enum values
var notAPill Pill = 42
if (notAPill.IsAPill()) {
	fmt.Println(notAPill, "is not a value of the Pill enum")
}

// 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"`

The generated code is exactly the same as the Stringer tool plus the mentioned additions, so you can use Enumer where you are already using Stringer without any code change.

Transforming the string representation of the enum value

By default, Enumer uses the same name of the enum value for generating the string representation (usually CamelCase in Go).

type MyType int

 ...

name := MyTypeValue.String() // name => "MyTypeValue"

Sometimes you need to use some other string representation format than CamelCase (i.e. in JSON).

To transform it from CamelCase to another format, you can use the transform flag.

For example, the command enumer -type=MyType -json -transform=snake would generate the following string representation:

name := MyTypeValue.String() // name => "my_type_value"

Note: The transformation only works from CamelCase to snake_case or kebab-case, not the other way around.

Transformers

  • snake
  • snake-upper
  • kebab
  • kebab-upper
  • lower (lowercase)
  • upper (UPPERCASE)
  • title (TitleCase)
  • title-lower (titleCase)
  • first (Use first character of string)
  • first-lower (same as first only lower case)
  • first-upper (same as first only upper case)
  • whitespace

How to use

For a module-aware repo with enumer in the go.mod file, generation can be called by adding the following to a .go source file:

//go:generate go run github.com/dmarkham/enumer -type=YOURTYPE

There are four boolean flags: json, text, yaml and sql. You can use any combination of them (i.e. enumer -type=Pill -json -text),

For enum string representation transformation the transform and trimprefix flags were added (i.e. enumer -type=MyType -json -transform=snake). Possible transform values are listed above in the transformers section. The default value for transform flag is noop which means no transformation will be performed.

If a prefix is provided via the trimprefix flag, it will be trimmed from the start of each name (before it is transformed). If a name doesn't have the prefix it will be passed unchanged.

If a prefix is provided via the addprefix flag, it will be added to the start of each name (after trimming and after transforming).

The boolean flag values will additionally create an alternative string values method Values() []string to fullfill the EnumValues interface of ent.

Inspiring projects

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].