Documentation ¶
Overview ¶
Package gen implements an enumeration generator.
Enumerations are described by a configuration. Each enumeration defines a type name and one or more enumerator values.
Type Structure ¶
The generated type is a struct containing an unexported small integer index to the string representation of the enumerator. Enumerators of the type can be compared for equality by value, and can be used as map keys. The zero value represents an unknown (invalid) enumerator; the Valid method reports whether an enumerator is valid (i.e., non-zero).
The String method returns a string representation for each enumerator, which defaults to the enumerator's base name. The Enum method returns the name of the enumeration type.
Enumerations generated by this package all satisfy this interface:
type EnumType interface { Enum() string // return the enumeration type name Index() int // return the integer index of the enumerator String() string // return the string representation of an enumerator Valid() bool // report whether the receiver is a valid nonzero enumerator }
Callers wishing to accept arbitrary enumerations may define this interface. It is not exported by the gen package to discourage inappropriate dependency on the code generator.
Configuration ¶
The gen.Config type defines a set of enumerations to generate in a single package. The general structure of a config in YAML is:
package: "name" # the name of the output package (required) enum: # a list of enumeration types to generate - type: "Name" # the type name for this enum prefix: "x" # (optional) prefix to append to each enumerator name zero: "Bad" # (optional) name of zero enumerator doc: "text" # (optional) documentation comment for the enum type val-doc: "text" # (optional) aggregate documentation for the values constructor: true # construct a New* function to convert strings to enumerators from-index: true # construct a *FromIndex function to convert integers to enumerators flag-value: true # implement the flag.Value interface on this enum text-marshal: true # implement the TextMarshaler/Unmarshaler interfaces on this enum values: - name: A # the name of the first enumerator (required) doc: "text" # (optional) documentation for this enumerator text: "aaa" # (optional) string text for the enumerator index: 25 # (optional) integer index for the enumerator - name: B # ... additional enumerators - name: C - type: "Other" values: - name: X - name: Y
Example ¶
package main import ( "log" "os" "github.com/creachadair/enumgen/gen" ) const input = `package example /*enumgen:type Example # package example inferred from the declaration above. # The type name assigned by the enumgen: comment. doc: Example is an example enumeration. values: - name: Good doc: upsides - name: Bad doc: downsides - name: Ugly doc: what it says on the tin */ ` func main() { cfg, err := gen.ConfigFromSource("example.go", []byte(input)) if err != nil { log.Fatalf("Parse: %v", err) } if err := cfg.Generate(os.Stdout); err != nil { log.Fatalf("Generate: %v", err) } }
Output: // Code generated by enumgen. DO NOT EDIT. package example // Example is an example enumeration. type Example struct{ _Example uint8 } // Enum returns the name of the enumeration type for Example. func (Example) Enum() string { return "Example" } // String returns the string representation of Example v. func (v Example) String() string { return _str_Example[v._Example] } // Valid reports whether v is a valid non-zero Example value. func (v Example) Valid() bool { return v._Example > 0 && int(v._Example) < len(_str_Example) } // Index returns the integer index of Example v. func (v Example) Index() int { return int(v._Example) } var ( _str_Example = []string{"<invalid>", "Good", "Bad", "Ugly"} Good = Example{1} // upsides Bad = Example{2} // downsides Ugly = Example{3} // what it says on the tin )
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { Package string // package name for the generated file (required) Enum []*Enum // enumerations to generate (at least one is required) }
A Config specifies a collection of enumerations in a single package.
func ConfigFromGoFile ¶ added in v0.2.2
ConfigFromGoFile reads and parses the Go file specified by path, and extracts a YAML config from each first comment block tagged enumgen:type found in the file. An error results if no such comment is found.
func ConfigFromSource ¶ added in v0.0.5
ConfigFromSource parses a config from the text of a Go source file. The path is used to for diagnostics.
func ConfigFromYAML ¶ added in v0.4.2
ConfigFromYAML reads and parses the YAML config file specified by path.
func LoadPackage ¶ added in v0.4.0
LoadPackage reads and parses a combined YAML configuration from the Go files stored in the current working directory.
An error is reported if the current working directory does not contain any Go source files with enumeration configurations in them, or if the files match multiple package names.
func ParseConfig ¶
ParseConfig parses a YAML configuration text from r.
func (*Config) Generate ¶
Generate generates the enumerations defined by c into w as Go source text.
If there is an error formatting the generated code, the unformatted code is still written to w before reporting the error. The caller should NOT use the output in case of error. Any error means there is a bug in the generator, and the output is written only to support debugging.
type Enum ¶
type Enum struct { Type string // enumeration type name (required) Values []*Value // the enumeration values (required) // If set, this prefix is prepended to each enumerator's variable name. // Otherwise, the variable name matches the Name field of the value. Prefix string // If set, this text is added as a doc comment for the enumeration. // Multiple lines are OK. The text should not contain comment markers. Doc string // If set, a variable is defined for the zero value with this name. // Typically a name like "Unknown" or "Invalid" makes sense. // Otherwise, no variable is defined for the zero value; the caller can // still construct a zero value explicitly if needed. // // Documentation and text for the zero value can be provided by including an // entry with this name in the list of values. Otherwise the zero value will // be undocumented and use a default string. The index of the zero value is // always 0, even if explicitly specified. Zero string // If set, this text is inserted at the top of the var block in the // generated code for the enumerator values. ValDoc string `yaml:"val-doc"` // If true, generate a New function to convert strings to enumerators. Constructor bool `yaml:"constructor"` // If true, generate a FromIndex function to convert integers to enumerators. FromIndex bool `yaml:"from-index"` // If true, generate methods to implement flag.Value for the type. FlagValue bool `yaml:"flag-value"` // If true, implement encoding.TextMarshaler for the type. TextMarshal bool `yaml:"text-marshal"` }
An Enum defines an enumeration type.
The generated type for an enumeration is a struct with an unexported pointer to the string representation of the enumerator. This representation allows cheap pointer comparisons, and users of the type outside the package cannot create new non-zero values of the type. The zero value is explicitly defined as the "unknown" value for an enumeration.
type Value ¶
type Value struct { Name string // enumerator name (required) // If set, this text is added as a doc comment for the enumerator value. If // it is a single line, it is added as a line comment; otherwise it is // placed before the enumerator. The text should not contain comment markers. // The placeholder {name} will be replaced with the final generated name of // the enumerator. Doc string // If set, this text is used as the string representation of the value. // Otherwise, the Name field is used. Text string // If non-nil, this value is used as the index of the value. Otherwise the // index is one greater than the previous value's index. Index *int }
A Value defines a single enumerator.