From 6ec30747dc7dc1437e91afed388a183685591d50 Mon Sep 17 00:00:00 2001 From: Xopherus Date: Tue, 12 Feb 2019 10:28:13 -0500 Subject: [PATCH 1/2] Add whitespace-separated transformation --- README.md | 8 +++++--- endtoend_test.go | 3 +++ stringer.go | 4 ++++ testdata/transform_whitespace.go | 25 +++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 testdata/transform_whitespace.go diff --git a/README.md b/README.md index 2cebb9f..87df7df 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ When Enumer is applied to a type, it will generate: - When the flag `sql` is provided, the methods for implementing the Scanner and Valuer interfaces will be also generated. Useful when storing the enum in a database. + For example, if we have an enum type called `Pill`, ```go @@ -120,7 +121,7 @@ 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 snake_case or kebab-case, you can use the `transform` flag. +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: @@ -128,7 +129,7 @@ For example, the command `enumer -type=MyType -json -transform=snake` would gene name := MyTypeValue.String() // name => "my_type_value" ``` -**Note**: The transformation only works form CamelCase to snake_case or kebab-case, not the other way around. +**Note**: The transformation only works from CamelCase to snake_case or kebab-case, not the other way around. ### Transformers @@ -142,6 +143,7 @@ name := MyTypeValue.String() // name => "my_type_value" - 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 @@ -152,7 +154,7 @@ There are four boolean flags: `json`, `text`, `yaml` and `sql`. You can use any For enum string representation transformation the `transform` and `trimprefix` flags 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. +Possible transform values are listed above in the [transformers](#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 diff --git a/endtoend_test.go b/endtoend_test.go index 10e0e39..5629e33 100644 --- a/endtoend_test.go +++ b/endtoend_test.go @@ -93,6 +93,9 @@ func TestEndToEnd(t *testing.T) { case "transform_first_lower.go": typeName = "FirstLowerCaseValue" transformNameMethod = "first-lower" + case "transform_whitespace.go": + typeName = "WhitespaceSeparatedValue" + transformNameMethod = "whitespace" default: typeName = fmt.Sprintf("%c%s", name[0]+'A'-'a', name[1:len(name)-len(".go")]) transformNameMethod = "noop" diff --git a/stringer.go b/stringer.go index e3ac91c..a57501d 100644 --- a/stringer.go +++ b/stringer.go @@ -286,6 +286,10 @@ func (g *Generator) transformValueNames(values []Value, transformMethod string) r, _ := utf8.DecodeRuneInString(s) return strings.ToLower(string(r)) } + case "whitespace": + fn = func(s string) string { + return strings.ToLower(name.Delimit(s, ' ')) + } default: return } diff --git a/testdata/transform_whitespace.go b/testdata/transform_whitespace.go new file mode 100644 index 0000000..b3d552d --- /dev/null +++ b/testdata/transform_whitespace.go @@ -0,0 +1,25 @@ +package main + +import "fmt" + +type WhitespaceSeparatedValue int + +const ( + WhitespaceSeparatedValueOne WhitespaceSeparatedValue = iota + WhitespaceSeparatedValueTwo + WhitespaceSeparatedValueThree +) + +func main() { + ck(WhitespaceSeparatedValueOne, "whitespace separated value one") + ck(WhitespaceSeparatedValueTwo, "whitespace separated value two") + ck(WhitespaceSeparatedValueThree, "whitespace separated value three") + ck(-127, "WhitespaceSeparatedValue(-127)") + ck(127, "WhitespaceSeparatedValue(127)") +} + +func ck(value WhitespaceSeparatedValue, str string) { + if fmt.Sprint(value) != str { + panic("transform_whitespace.go: " + str) + } +} From f84898d4c3aecf60f050bce496bcb1b22199799d Mon Sep 17 00:00:00 2001 From: Michael Gaffney Date: Fri, 1 Mar 2019 15:36:43 -0500 Subject: [PATCH 2/2] Fix generated comments - Add missing punctuation marks. - Make comments more consistent with comments for similar functions in the standard library. --- enumer.go | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/enumer.go b/enumer.go index 6c3d6fd..45e5dc8 100644 --- a/enumer.go +++ b/enumer.go @@ -4,8 +4,8 @@ import "fmt" // Arguments to format are: // [1]: type 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. +const stringNameToValueMethod = `// %[1]sString returns a %[1]s for s. +// It returns an error if s is not a %[1]s. func %[1]sString(s string) (%[1]s, error) { if val, ok := _%[1]sNameToValueMap[s]; ok { return val, nil @@ -16,7 +16,7 @@ func %[1]sString(s string) (%[1]s, error) { // Arguments to format are: // [1]: type name -const stringValuesMethod = `// %[1]sValues returns all values of the enum +const stringValuesMethod = `// %[1]sValues returns all values of the enum. func %[1]sValues() []%[1]s { return _%[1]sValues } @@ -24,7 +24,7 @@ func %[1]sValues() []%[1]s { // Arguments to format are: // [1]: type name -const stringBelongsMethodLoop = `// IsA%[1]s returns "true" if the value is listed in the enum definition. "false" otherwise +const stringBelongsMethodLoop = `// IsA%[1]s reports whether the value is a member of the enum. func (i %[1]s) IsA%[1]s() bool { for _, v := range _%[1]sValues { if i == v { @@ -37,9 +37,9 @@ func (i %[1]s) IsA%[1]s() bool { // Arguments to format are: // [1]: type name -const stringBelongsMethodSet = `// IsA%[1]s returns "true" if the value is listed in the enum definition. "false" otherwise +const stringBelongsMethodSet = `// IsA%[1]s reports whether the value is a member of the enum. func (i %[1]s) IsA%[1]s() bool { - _, ok := _%[1]sMap[i] + _, ok := _%[1]sMap[i] return ok } ` @@ -88,13 +88,12 @@ func (g *Generator) buildBasicExtras(runs [][]Value, typeName string, runsThresh // Arguments to format are: // [1]: type name -const jsonMethods = ` -// MarshalJSON implements the json.Marshaler interface for %[1]s +const jsonMethods = `// MarshalJSON implements the json.Marshaler interface. func (i %[1]s) MarshalJSON() ([]byte, error) { return json.Marshal(i.String()) } -// UnmarshalJSON implements the json.Unmarshaler interface for %[1]s +// UnmarshalJSON implements the json.Unmarshaler interface. func (i *%[1]s) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { @@ -114,12 +113,12 @@ func (g *Generator) buildJSONMethods(runs [][]Value, typeName string, runsThresh // Arguments to format are: // [1]: type name const textMethods = ` -// MarshalText implements the encoding.TextMarshaler interface for %[1]s +// MarshalText implements the encoding.TextMarshaler interface. func (i %[1]s) MarshalText() ([]byte, error) { return []byte(i.String()), nil } -// UnmarshalText implements the encoding.TextUnmarshaler interface for %[1]s +// UnmarshalText implements the encoding.TextUnmarshaler interface. func (i *%[1]s) UnmarshalText(text []byte) error { var err error *i, err = %[1]sString(string(text)) @@ -133,13 +132,12 @@ func (g *Generator) buildTextMethods(runs [][]Value, typeName string, runsThresh // Arguments to format are: // [1]: type name -const yamlMethods = ` -// MarshalYAML implements a YAML Marshaler for %[1]s +const yamlMethods = `// MarshalYAML implements the yaml.Marshaler interface. func (i %[1]s) MarshalYAML() (interface{}, error) { return i.String(), nil } -// UnmarshalYAML implements a YAML Unmarshaler for %[1]s +// UnmarshalYAML implements the yaml.Unmarshaler interface. func (i *%[1]s) UnmarshalYAML(unmarshal func(interface{}) error) error { var s string if err := unmarshal(&s); err != nil {