diff --git a/README.md b/README.md index ee79eb6..817defd 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ Flags: if true, json marshaling methods will be generated. Default: false -linecomment use line comment text as printed text when present + -tostring + if true, ToString function that returns an number-based string will be generated. Default: false -output string output file name; default srcdir/_string.go -sql @@ -71,6 +73,9 @@ When Enumer is applied to a type, it will generate: 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. +- When the flag `tostring` is provided, the methods for implementing the `ToString` interfaces. + the `ToString` interface, Instead of an enumerated string, get a defined number-based string. + For example, if we have an enum type called `Pill`, diff --git a/golden_test.go b/golden_test.go index 03479d2..e65a646 100644 --- a/golden_test.go +++ b/golden_test.go @@ -33,6 +33,15 @@ var golden = []Golden{ {"prime", primeIn}, } +var goldenToString = []Golden{ + {"tostring_day", dayIn}, + {"tostring_offset", offsetIn}, + {"tostring_gap", gapIn}, + {"tostring_num", numIn}, + {"tostring_unum", unumIn}, + {"tostring_prime", primeIn}, +} + var goldenJSON = []Golden{ {"primeJson", primeJsonIn}, } @@ -315,45 +324,48 @@ const ( func TestGolden(t *testing.T) { for _, test := range golden { - runGoldenTest(t, test, false, false, false, false, false, false, true, "", "") + runGoldenTest(t, test, false, false, false, false, false, false, true, false, "", "") + } + for _, test := range goldenToString { + runGoldenTest(t, test, false, false, false, false, false, false, false, true, "", "") } for _, test := range goldenJSON { - runGoldenTest(t, test, true, false, false, false, false, false, false, "", "") + runGoldenTest(t, test, true, false, false, false, false, false, false, false, "", "") } for _, test := range goldenText { - runGoldenTest(t, test, false, false, false, true, false, false, false, "", "") + runGoldenTest(t, test, false, false, false, true, false, false, false, false, "", "") } for _, test := range goldenYAML { - runGoldenTest(t, test, false, true, false, false, false, false, false, "", "") + runGoldenTest(t, test, false, true, false, false, false, false, false, false, "", "") } for _, test := range goldenSQL { - runGoldenTest(t, test, false, false, true, false, false, false, false, "", "") + runGoldenTest(t, test, false, false, true, false, false, false, false, false, "", "") } for _, test := range goldenJSONAndSQL { - runGoldenTest(t, test, true, false, true, false, false, false, false, "", "") + runGoldenTest(t, test, true, false, true, false, false, false, false, false, "", "") } for _, test := range goldenGQLGen { - runGoldenTest(t, test, false, false, false, false, false, true, false, "", "") + runGoldenTest(t, test, false, false, false, false, false, true, false, false, "", "") } for _, test := range goldenTrimPrefix { - runGoldenTest(t, test, false, false, false, false, false, false, false, "Day", "") + runGoldenTest(t, test, false, false, false, false, false, false, false, false, "Day", "") } for _, test := range goldenTrimPrefixMultiple { - runGoldenTest(t, test, false, false, false, false, false, false, false, "Day,Night", "") + runGoldenTest(t, test, false, false, false, false, false, false, false, false, "Day,Night", "") } for _, test := range goldenWithPrefix { - runGoldenTest(t, test, false, false, false, false, false, false, false, "", "Day") + runGoldenTest(t, test, false, false, false, false, false, false, false, false, "", "Day") } for _, test := range goldenTrimAndAddPrefix { - runGoldenTest(t, test, false, false, false, false, false, false, false, "Day", "Night") + runGoldenTest(t, test, false, false, false, false, false, false, false, false, "Day", "Night") } for _, test := range goldenLinecomment { - runGoldenTest(t, test, false, false, false, false, true, false, false, "", "") + runGoldenTest(t, test, false, false, false, false, true, false, false, false, "", "") } } func runGoldenTest(t *testing.T, test Golden, - generateJSON, generateYAML, generateSQL, generateText, linecomment, generateGQLGen, generateValuesMethod bool, + generateJSON, generateYAML, generateSQL, generateText, linecomment, generateGQLGen, generateValuesMethod, toString bool, trimPrefix string, prefix string) { var g Generator @@ -382,7 +394,7 @@ func runGoldenTest(t *testing.T, test Golden, if len(tokens) != 3 { t.Fatalf("%s: need type declaration on first line", test.name) } - g.generate(tokens[1], generateJSON, generateYAML, generateSQL, generateText, generateGQLGen, "noop", trimPrefix, prefix, linecomment, generateValuesMethod) + g.generate(tokens[1], generateJSON, generateYAML, generateSQL, generateText, generateGQLGen, "noop", trimPrefix, prefix, linecomment, generateValuesMethod, toString) got := string(g.format()) if got != loadGolden(test.name) { // Use this to help build a golden text when changes are needed diff --git a/stringer.go b/stringer.go index 49c87fd..6cb5b03 100644 --- a/stringer.go +++ b/stringer.go @@ -56,6 +56,7 @@ var ( trimPrefix = flag.String("trimprefix", "", "transform each item name by removing a prefix. Default: \"\"") addPrefix = flag.String("addprefix", "", "transform each item name by adding a prefix. Default: \"\"") linecomment = flag.Bool("linecomment", false, "use line comment text as printed text when present") + tostring = flag.Bool("tostring", false, "if true, ToString function that returns an number-based string will be generated. Default: false") ) var comments arrayFlags @@ -135,7 +136,7 @@ func main() { // Run generate for each type. for _, typeName := range typs { - g.generate(typeName, *json, *yaml, *sql, *text, *gqlgen, *transformMethod, *trimPrefix, *addPrefix, *linecomment, *altValuesFunc) + g.generate(typeName, *json, *yaml, *sql, *text, *gqlgen, *transformMethod, *trimPrefix, *addPrefix, *linecomment, *altValuesFunc, *tostring) } // Format the output. @@ -415,7 +416,8 @@ func (g *Generator) prefixValueNames(values []Value, prefix string) { // generate produces the String method for the named type. func (g *Generator) generate(typeName string, includeJSON, includeYAML, includeSQL, includeText, includeGQLGen bool, - transformMethod string, trimPrefix string, addPrefix string, lineComment bool, includeValuesMethod bool) { + transformMethod string, trimPrefix string, addPrefix string, lineComment bool, includeValuesMethod bool, + toString bool) { values := make([]Value, 0, 100) for _, file := range g.pkg.files { file.lineComment = lineComment @@ -465,6 +467,9 @@ func (g *Generator) generate(typeName string, if includeValuesMethod { g.buildAltStringValuesMethod(typeName) } + if toString { + g.buildToStringMethod(typeName) + } g.buildNoOpOrderChangeDetect(runs, typeName) @@ -774,9 +779,10 @@ func (g *Generator) buildOneRun(runs [][]Value, typeName string) { } // Arguments to format are: -// [1]: type name -// [2]: size of index element (8 for uint8 etc.) -// [3]: less than zero check (for signed types) +// +// [1]: type name +// [2]: size of index element (8 for uint8 etc.) +// [3]: less than zero check (for signed types) const stringOneRun = `func (i %[1]s) String() string { if %[3]si >= %[1]s(len(_%[1]sIndex)-1) { return fmt.Sprintf("%[1]s(%%d)", i) @@ -786,10 +792,11 @@ const stringOneRun = `func (i %[1]s) String() string { ` // Arguments to format are: -// [1]: type name -// [2]: lowest defined value for type, as a string -// [3]: size of index element (8 for uint8 etc.) -// [4]: less than zero check (for signed types) +// +// [1]: type name +// [2]: lowest defined value for type, as a string +// [3]: size of index element (8 for uint8 etc.) +// [4]: less than zero check (for signed types) const stringOneRunWithOffset = `func (i %[1]s) String() string { i -= %[2]s if %[4]si >= %[1]s(len(_%[1]sIndex)-1) { @@ -868,3 +875,18 @@ const stringMap = `func (i %[1]s) String() string { return fmt.Sprintf("%[1]s(%%d)", i) } ` + +func (g *Generator) buildToStringMethod(typeName string) { + g.Printf(toStringFromInt, typeName) +} + +// Arguments to format are: +// +// [1]: type name +// [2]: size of index element (8 for uint8 etc.) +// [3]: less than zero check (for signed types) +const toStringFromInt = `// ToString converts %[1]s to an int-based string and returns it. +func (i %[1]s) ToString() string { + return strconv.Itoa(int(i)) +} +` diff --git a/testdata/tostring_day.golden b/testdata/tostring_day.golden new file mode 100644 index 0000000..f3c7bca --- /dev/null +++ b/testdata/tostring_day.golden @@ -0,0 +1,95 @@ + +const _DayName = "MondayTuesdayWednesdayThursdayFridaySaturdaySunday" + +var _DayIndex = [...]uint8{0, 6, 13, 22, 30, 36, 44, 50} + +const _DayLowerName = "mondaytuesdaywednesdaythursdayfridaysaturdaysunday" + +func (i Day) String() string { + if i < 0 || i >= Day(len(_DayIndex)-1) { + return fmt.Sprintf("Day(%d)", i) + } + return _DayName[_DayIndex[i]:_DayIndex[i+1]] +} + +// ToString converts Day to an int-based string and returns it. +func (i Day) ToString() string { + return strconv.Itoa(int(i)) +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _DayNoOp() { + var x [1]struct{} + _ = x[Monday-(0)] + _ = x[Tuesday-(1)] + _ = x[Wednesday-(2)] + _ = x[Thursday-(3)] + _ = x[Friday-(4)] + _ = x[Saturday-(5)] + _ = x[Sunday-(6)] +} + +var _DayValues = []Day{Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday} + +var _DayNameToValueMap = map[string]Day{ + _DayName[0:6]: Monday, + _DayLowerName[0:6]: Monday, + _DayName[6:13]: Tuesday, + _DayLowerName[6:13]: Tuesday, + _DayName[13:22]: Wednesday, + _DayLowerName[13:22]: Wednesday, + _DayName[22:30]: Thursday, + _DayLowerName[22:30]: Thursday, + _DayName[30:36]: Friday, + _DayLowerName[30:36]: Friday, + _DayName[36:44]: Saturday, + _DayLowerName[36:44]: Saturday, + _DayName[44:50]: Sunday, + _DayLowerName[44:50]: Sunday, +} + +var _DayNames = []string{ + _DayName[0:6], + _DayName[6:13], + _DayName[13:22], + _DayName[22:30], + _DayName[30:36], + _DayName[36:44], + _DayName[44:50], +} + +// DayString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func DayString(s string) (Day, error) { + if val, ok := _DayNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _DayNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to Day values", s) +} + +// DayValues returns all values of the enum +func DayValues() []Day { + return _DayValues +} + +// DayStrings returns a slice of all String values of the enum +func DayStrings() []string { + strs := make([]string, len(_DayNames)) + copy(strs, _DayNames) + return strs +} + +// IsADay returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Day) IsADay() bool { + for _, v := range _DayValues { + if i == v { + return true + } + } + return false +} diff --git a/testdata/tostring_gap.golden b/testdata/tostring_gap.golden new file mode 100644 index 0000000..7e767f4 --- /dev/null +++ b/testdata/tostring_gap.golden @@ -0,0 +1,116 @@ + +const ( + _GapName_0 = "TwoThree" + _GapLowerName_0 = "twothree" + _GapName_1 = "FiveSixSevenEightNine" + _GapLowerName_1 = "fivesixseveneightnine" + _GapName_2 = "Eleven" + _GapLowerName_2 = "eleven" +) + +var ( + _GapIndex_0 = [...]uint8{0, 3, 8} + _GapIndex_1 = [...]uint8{0, 4, 7, 12, 17, 21} + _GapIndex_2 = [...]uint8{0, 6} +) + +func (i Gap) String() string { + switch { + case 2 <= i && i <= 3: + i -= 2 + return _GapName_0[_GapIndex_0[i]:_GapIndex_0[i+1]] + case 5 <= i && i <= 9: + i -= 5 + return _GapName_1[_GapIndex_1[i]:_GapIndex_1[i+1]] + case i == 11: + return _GapName_2 + default: + return fmt.Sprintf("Gap(%d)", i) + } +} + +// ToString converts Gap to an int-based string and returns it. +func (i Gap) ToString() string { + return strconv.Itoa(int(i)) +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _GapNoOp() { + var x [1]struct{} + _ = x[Two-(2)] + _ = x[Three-(3)] + _ = x[Five-(5)] + _ = x[Six-(6)] + _ = x[Seven-(7)] + _ = x[Eight-(8)] + _ = x[Nine-(9)] + _ = x[Eleven-(11)] +} + +var _GapValues = []Gap{Two, Three, Five, Six, Seven, Eight, Nine, Eleven} + +var _GapNameToValueMap = map[string]Gap{ + _GapName_0[0:3]: Two, + _GapLowerName_0[0:3]: Two, + _GapName_0[3:8]: Three, + _GapLowerName_0[3:8]: Three, + _GapName_1[0:4]: Five, + _GapLowerName_1[0:4]: Five, + _GapName_1[4:7]: Six, + _GapLowerName_1[4:7]: Six, + _GapName_1[7:12]: Seven, + _GapLowerName_1[7:12]: Seven, + _GapName_1[12:17]: Eight, + _GapLowerName_1[12:17]: Eight, + _GapName_1[17:21]: Nine, + _GapLowerName_1[17:21]: Nine, + _GapName_2[0:6]: Eleven, + _GapLowerName_2[0:6]: Eleven, +} + +var _GapNames = []string{ + _GapName_0[0:3], + _GapName_0[3:8], + _GapName_1[0:4], + _GapName_1[4:7], + _GapName_1[7:12], + _GapName_1[12:17], + _GapName_1[17:21], + _GapName_2[0:6], +} + +// GapString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func GapString(s string) (Gap, error) { + if val, ok := _GapNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _GapNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to Gap values", s) +} + +// GapValues returns all values of the enum +func GapValues() []Gap { + return _GapValues +} + +// GapStrings returns a slice of all String values of the enum +func GapStrings() []string { + strs := make([]string, len(_GapNames)) + copy(strs, _GapNames) + return strs +} + +// IsAGap returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Gap) IsAGap() bool { + for _, v := range _GapValues { + if i == v { + return true + } + } + return false +} diff --git a/testdata/tostring_num.golden b/testdata/tostring_num.golden new file mode 100644 index 0000000..407c538 --- /dev/null +++ b/testdata/tostring_num.golden @@ -0,0 +1,88 @@ + +const _NumName = "m_2m_1m0m1m2" + +var _NumIndex = [...]uint8{0, 3, 6, 8, 10, 12} + +const _NumLowerName = "m_2m_1m0m1m2" + +func (i Num) String() string { + i -= -2 + if i < 0 || i >= Num(len(_NumIndex)-1) { + return fmt.Sprintf("Num(%d)", i+-2) + } + return _NumName[_NumIndex[i]:_NumIndex[i+1]] +} + +// ToString converts Num to an int-based string and returns it. +func (i Num) ToString() string { + return strconv.Itoa(int(i)) +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _NumNoOp() { + var x [1]struct{} + _ = x[m_2-(-2)] + _ = x[m_1-(-1)] + _ = x[m0-(0)] + _ = x[m1-(1)] + _ = x[m2-(2)] +} + +var _NumValues = []Num{m_2, m_1, m0, m1, m2} + +var _NumNameToValueMap = map[string]Num{ + _NumName[0:3]: m_2, + _NumLowerName[0:3]: m_2, + _NumName[3:6]: m_1, + _NumLowerName[3:6]: m_1, + _NumName[6:8]: m0, + _NumLowerName[6:8]: m0, + _NumName[8:10]: m1, + _NumLowerName[8:10]: m1, + _NumName[10:12]: m2, + _NumLowerName[10:12]: m2, +} + +var _NumNames = []string{ + _NumName[0:3], + _NumName[3:6], + _NumName[6:8], + _NumName[8:10], + _NumName[10:12], +} + +// NumString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func NumString(s string) (Num, error) { + if val, ok := _NumNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _NumNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to Num values", s) +} + +// NumValues returns all values of the enum +func NumValues() []Num { + return _NumValues +} + +// NumStrings returns a slice of all String values of the enum +func NumStrings() []string { + strs := make([]string, len(_NumNames)) + copy(strs, _NumNames) + return strs +} + +// IsANum returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Num) IsANum() bool { + for _, v := range _NumValues { + if i == v { + return true + } + } + return false +} diff --git a/testdata/tostring_offset.golden b/testdata/tostring_offset.golden new file mode 100644 index 0000000..a7d2c49 --- /dev/null +++ b/testdata/tostring_offset.golden @@ -0,0 +1,80 @@ + +const _NumberName = "OneTwoThree" + +var _NumberIndex = [...]uint8{0, 3, 6, 11} + +const _NumberLowerName = "onetwothree" + +func (i Number) String() string { + i -= 1 + if i < 0 || i >= Number(len(_NumberIndex)-1) { + return fmt.Sprintf("Number(%d)", i+1) + } + return _NumberName[_NumberIndex[i]:_NumberIndex[i+1]] +} + +// ToString converts Number to an int-based string and returns it. +func (i Number) ToString() string { + return strconv.Itoa(int(i)) +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _NumberNoOp() { + var x [1]struct{} + _ = x[One-(1)] + _ = x[Two-(2)] + _ = x[Three-(3)] +} + +var _NumberValues = []Number{One, Two, Three} + +var _NumberNameToValueMap = map[string]Number{ + _NumberName[0:3]: One, + _NumberLowerName[0:3]: One, + _NumberName[3:6]: Two, + _NumberLowerName[3:6]: Two, + _NumberName[6:11]: Three, + _NumberLowerName[6:11]: Three, +} + +var _NumberNames = []string{ + _NumberName[0:3], + _NumberName[3:6], + _NumberName[6:11], +} + +// NumberString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func NumberString(s string) (Number, error) { + if val, ok := _NumberNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _NumberNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to Number values", s) +} + +// NumberValues returns all values of the enum +func NumberValues() []Number { + return _NumberValues +} + +// NumberStrings returns a slice of all String values of the enum +func NumberStrings() []string { + strs := make([]string, len(_NumberNames)) + copy(strs, _NumberNames) + return strs +} + +// IsANumber returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Number) IsANumber() bool { + for _, v := range _NumberValues { + if i == v { + return true + } + } + return false +} diff --git a/testdata/tostring_prime.golden b/testdata/tostring_prime.golden new file mode 100644 index 0000000..ad12e85 --- /dev/null +++ b/testdata/tostring_prime.golden @@ -0,0 +1,128 @@ + +const _PrimeName = "p2p3p5p7p11p13p17p19p23p29p37p41p43" +const _PrimeLowerName = "p2p3p5p7p11p13p17p19p23p29p37p41p43" + +var _PrimeMap = map[Prime]string{ + 2: _PrimeName[0:2], + 3: _PrimeName[2:4], + 5: _PrimeName[4:6], + 7: _PrimeName[6:8], + 11: _PrimeName[8:11], + 13: _PrimeName[11:14], + 17: _PrimeName[14:17], + 19: _PrimeName[17:20], + 23: _PrimeName[20:23], + 29: _PrimeName[23:26], + 31: _PrimeName[26:29], + 41: _PrimeName[29:32], + 43: _PrimeName[32:35], +} + +func (i Prime) String() string { + if str, ok := _PrimeMap[i]; ok { + return str + } + return fmt.Sprintf("Prime(%d)", i) +} + +// ToString converts Prime to an int-based string and returns it. +func (i Prime) ToString() string { + return strconv.Itoa(int(i)) +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _PrimeNoOp() { + var x [1]struct{} + _ = x[p2-(2)] + _ = x[p3-(3)] + _ = x[p5-(5)] + _ = x[p7-(7)] + _ = x[p11-(11)] + _ = x[p13-(13)] + _ = x[p17-(17)] + _ = x[p19-(19)] + _ = x[p23-(23)] + _ = x[p29-(29)] + _ = x[p37-(31)] + _ = x[p41-(41)] + _ = x[p43-(43)] +} + +var _PrimeValues = []Prime{p2, p3, p5, p7, p11, p13, p17, p19, p23, p29, p37, p41, p43} + +var _PrimeNameToValueMap = map[string]Prime{ + _PrimeName[0:2]: p2, + _PrimeLowerName[0:2]: p2, + _PrimeName[2:4]: p3, + _PrimeLowerName[2:4]: p3, + _PrimeName[4:6]: p5, + _PrimeLowerName[4:6]: p5, + _PrimeName[6:8]: p7, + _PrimeLowerName[6:8]: p7, + _PrimeName[8:11]: p11, + _PrimeLowerName[8:11]: p11, + _PrimeName[11:14]: p13, + _PrimeLowerName[11:14]: p13, + _PrimeName[14:17]: p17, + _PrimeLowerName[14:17]: p17, + _PrimeName[17:20]: p19, + _PrimeLowerName[17:20]: p19, + _PrimeName[20:23]: p23, + _PrimeLowerName[20:23]: p23, + _PrimeName[23:26]: p29, + _PrimeLowerName[23:26]: p29, + _PrimeName[26:29]: p37, + _PrimeLowerName[26:29]: p37, + _PrimeName[29:32]: p41, + _PrimeLowerName[29:32]: p41, + _PrimeName[32:35]: p43, + _PrimeLowerName[32:35]: p43, +} + +var _PrimeNames = []string{ + _PrimeName[0:2], + _PrimeName[2:4], + _PrimeName[4:6], + _PrimeName[6:8], + _PrimeName[8:11], + _PrimeName[11:14], + _PrimeName[14:17], + _PrimeName[17:20], + _PrimeName[20:23], + _PrimeName[23:26], + _PrimeName[26:29], + _PrimeName[29:32], + _PrimeName[32:35], +} + +// PrimeString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func PrimeString(s string) (Prime, error) { + if val, ok := _PrimeNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _PrimeNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to Prime values", s) +} + +// PrimeValues returns all values of the enum +func PrimeValues() []Prime { + return _PrimeValues +} + +// PrimeStrings returns a slice of all String values of the enum +func PrimeStrings() []string { + strs := make([]string, len(_PrimeNames)) + copy(strs, _PrimeNames) + return strs +} + +// IsAPrime returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Prime) IsAPrime() bool { + _, ok := _PrimeMap[i] + return ok +} diff --git a/testdata/tostring_unum.golden b/testdata/tostring_unum.golden new file mode 100644 index 0000000..4637393 --- /dev/null +++ b/testdata/tostring_unum.golden @@ -0,0 +1,98 @@ + +const ( + _UnumName_0 = "m0m1m2" + _UnumLowerName_0 = "m0m1m2" + _UnumName_1 = "m_2m_1" + _UnumLowerName_1 = "m_2m_1" +) + +var ( + _UnumIndex_0 = [...]uint8{0, 2, 4, 6} + _UnumIndex_1 = [...]uint8{0, 3, 6} +) + +func (i Unum) String() string { + switch { + case 0 <= i && i <= 2: + return _UnumName_0[_UnumIndex_0[i]:_UnumIndex_0[i+1]] + case 253 <= i && i <= 254: + i -= 253 + return _UnumName_1[_UnumIndex_1[i]:_UnumIndex_1[i+1]] + default: + return fmt.Sprintf("Unum(%d)", i) + } +} + +// ToString converts Unum to an int-based string and returns it. +func (i Unum) ToString() string { + return strconv.Itoa(int(i)) +} + +// An "invalid array index" compiler error signifies that the constant values have changed. +// Re-run the stringer command to generate them again. +func _UnumNoOp() { + var x [1]struct{} + _ = x[m0-(0)] + _ = x[m1-(1)] + _ = x[m2-(2)] + _ = x[m_2-(253)] + _ = x[m_1-(254)] +} + +var _UnumValues = []Unum{m0, m1, m2, m_2, m_1} + +var _UnumNameToValueMap = map[string]Unum{ + _UnumName_0[0:2]: m0, + _UnumLowerName_0[0:2]: m0, + _UnumName_0[2:4]: m1, + _UnumLowerName_0[2:4]: m1, + _UnumName_0[4:6]: m2, + _UnumLowerName_0[4:6]: m2, + _UnumName_1[0:3]: m_2, + _UnumLowerName_1[0:3]: m_2, + _UnumName_1[3:6]: m_1, + _UnumLowerName_1[3:6]: m_1, +} + +var _UnumNames = []string{ + _UnumName_0[0:2], + _UnumName_0[2:4], + _UnumName_0[4:6], + _UnumName_1[0:3], + _UnumName_1[3:6], +} + +// UnumString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func UnumString(s string) (Unum, error) { + if val, ok := _UnumNameToValueMap[s]; ok { + return val, nil + } + + if val, ok := _UnumNameToValueMap[strings.ToLower(s)]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to Unum values", s) +} + +// UnumValues returns all values of the enum +func UnumValues() []Unum { + return _UnumValues +} + +// UnumStrings returns a slice of all String values of the enum +func UnumStrings() []string { + strs := make([]string, len(_UnumNames)) + copy(strs, _UnumNames) + return strs +} + +// IsAUnum returns "true" if the value is listed in the enum definition. "false" otherwise +func (i Unum) IsAUnum() bool { + for _, v := range _UnumValues { + if i == v { + return true + } + } + return false +}