diff --git a/enumer.go b/enumer.go index 95c0000..c73dbb4 100644 --- a/enumer.go +++ b/enumer.go @@ -4,7 +4,7 @@ import "fmt" // Arguments to format are: // [1]: type name -const stringValueToNameMap = `// %[1]sString retrieves an enum value from the enum constants string name. +const stringNameToValueMethod = `// %[1]sString retrieves an enum value from the enum constants string name. // Throws an error if the param is not part of the enum. func %[1]sString(s string) (%[1]s, error) { if val, ok := _%[1]sNameToValueMap[s]; ok { @@ -14,8 +14,40 @@ func %[1]sString(s string) (%[1]s, error) { } ` -func (g *Generator) buildValueToNameMap(runs [][]Value, typeName string, runsThreshold int) { +// Arguments to format are: +// [1]: type name +const stringValuesMethod = `// %[1]sValues returns all values of the enum +func %[1]sValues() []%[1]s { + return _%[1]sValues +} +` + +// Arguments to format are: +// [1]: type name +const stringBelongsMethod = `// belongsTo%[1]s returns "true" if the value is listed in the enum definition. "false" otherwise +func (i %[1]s) belongsTo%[1]s() bool { + for _, v := range _%[1]sValues { + if i == v { + return true + } + } + return false +} +` + +func (g *Generator) buildBasicExtras(runs [][]Value, typeName string, runsThreshold int) { // At this moment, either "g.declareIndexAndNameVars()" or "g.declareNameVars()" has been called + + // Print the slice of values + g.Printf("\nvar _%sValues = []%s{", typeName, typeName) + for _, values := range runs { + for _, value := range values { + g.Printf("\t%s, ", value.str) + } + } + g.Printf("}\n\n") + + // Print the map between name and value g.Printf("\nvar _%sNameToValueMap = map[string]%s{\n", typeName, typeName) thereAreRuns := len(runs) > 1 && len(runs) <= runsThreshold var n int @@ -34,7 +66,11 @@ func (g *Generator) buildValueToNameMap(runs [][]Value, typeName string, runsThr } } g.Printf("}\n\n") - g.Printf(stringValueToNameMap, typeName) + + // Print the basic extra methods + g.Printf(stringNameToValueMethod, typeName) + g.Printf(stringValuesMethod, typeName) + g.Printf(stringBelongsMethod, typeName) } // Arguments to format are: diff --git a/golden_test.go b/golden_test.go index 23eaf64..3a9e15d 100644 --- a/golden_test.go +++ b/golden_test.go @@ -80,6 +80,8 @@ func (i Day) String() string { return _DayName[_DayIndex[i]:_DayIndex[i+1]] } +var _DayValues = []Day{0, 1, 2, 3, 4, 5, 6} + var _DayNameToValueMap = map[string]Day{ _DayName[0:6]: 0, _DayName[6:13]: 1, @@ -98,6 +100,21 @@ func DayString(s string) (Day, error) { } return 0, fmt.Errorf("%s does not belong to Day values", s) } + +// DayValues returns all values of the enum +func DayValues() []Day { + return _DayValues +} + +// belongsToDay returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Day) belongsToDay() bool { + for _, v := range _DayValues { + if i == v { + return true + } + } + return false +} ` // Enumeration with an offset. @@ -125,6 +142,8 @@ func (i Number) String() string { return _NumberName[_NumberIndex[i]:_NumberIndex[i+1]] } +var _NumberValues = []Number{1, 2, 3} + var _NumberNameToValueMap = map[string]Number{ _NumberName[0:3]: 1, _NumberName[3:6]: 2, @@ -139,6 +158,21 @@ func NumberString(s string) (Number, error) { } return 0, fmt.Errorf("%s does not belong to Number values", s) } + +// NumberValues returns all values of the enum +func NumberValues() []Number { + return _NumberValues +} + +// belongsToNumber returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Number) belongsToNumber() bool { + for _, v := range _NumberValues { + if i == v { + return true + } + } + return false +} ` // Gaps and an offset. @@ -183,6 +217,8 @@ func (i Gap) String() string { } } +var _GapValues = []Gap{2, 3, 5, 6, 7, 8, 9, 11} + var _GapNameToValueMap = map[string]Gap{ _GapName_0[0:3]: 2, _GapName_0[3:8]: 3, @@ -202,6 +238,21 @@ func GapString(s string) (Gap, error) { } return 0, fmt.Errorf("%s does not belong to Gap values", s) } + +// GapValues returns all values of the enum +func GapValues() []Gap { + return _GapValues +} + +// belongsToGap returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Gap) belongsToGap() bool { + for _, v := range _GapValues { + if i == v { + return true + } + } + return false +} ` // Signed integers spanning zero. @@ -228,6 +279,8 @@ func (i Num) String() string { return _NumName[_NumIndex[i]:_NumIndex[i+1]] } +var _NumValues = []Num{-2, -1, 0, 1, 2} + var _NumNameToValueMap = map[string]Num{ _NumName[0:3]: -2, _NumName[3:6]: -1, @@ -244,6 +297,21 @@ func NumString(s string) (Num, error) { } return 0, fmt.Errorf("%s does not belong to Num values", s) } + +// NumValues returns all values of the enum +func NumValues() []Num { + return _NumValues +} + +// belongsToNum returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Num) belongsToNum() bool { + for _, v := range _NumValues { + if i == v { + return true + } + } + return false +} ` // Unsigned integers spanning zero. @@ -283,6 +351,8 @@ func (i Unum) String() string { } } +var _UnumValues = []Unum{0, 1, 2, 253, 254} + var _UnumNameToValueMap = map[string]Unum{ _UnumName_0[0:2]: 0, _UnumName_0[2:4]: 1, @@ -299,6 +369,21 @@ func UnumString(s string) (Unum, error) { } return 0, fmt.Errorf("%s does not belong to Unum values", s) } + +// UnumValues returns all values of the enum +func UnumValues() []Unum { + return _UnumValues +} + +// belongsToUnum returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Unum) belongsToUnum() bool { + for _, v := range _UnumValues { + if i == v { + return true + } + } + return false +} ` // Enough gaps to trigger a map implementation of the method. diff --git a/stringer.go b/stringer.go index 10f3219..34447fb 100644 --- a/stringer.go +++ b/stringer.go @@ -359,7 +359,7 @@ func (g *Generator) generate(typeName string, includeJSON, includeYAML, includeS g.buildMap(runs, typeName) } - g.buildValueToNameMap(runs, typeName, runsThreshold) + g.buildBasicExtras(runs, typeName, runsThreshold) if includeJSON { g.buildJSONMethods(runs, typeName, runsThreshold) }