Repository: abice/go-enum
Pull request #256 (2025-03-04 16:16:49)

fix: fixed generation of string enums with one char being a backtick, single quote or double quote
I'm writing some constants for working with a PDF.
A PDF has the operators `'` and `"`, when I tried to create constants for these operators it would generated an invalid file.
The constant value would be correct, like `OPMoveToNextLineSetSpacingShowText OP = "\""`, which is valid, but in the `_OPValue` map it would create a key with the value `"\\\""`, which is invalid.
I updated the code to fix that. It passes all the previous tests and now it generates the proper value and the proper key.


Patch:
diff --git a/generator/enum_string.tmpl b/generator/enum_string.tmpl
index 41f1623..4fbb096 100644
--- a/generator/enum_string.tmpl
+++ b/generator/enum_string.tmpl
@@ -10,7 +10,7 @@ const (
 	{{- if $value.Comment}}
 	// {{$value.Comment}}
 	{{- end}}
-    {{$value.PrefixedName}} {{$enumName}} = "{{$value.ValueStr}}"
+    {{$value.PrefixedName}} {{$enumName}} = {{quote $value.ValueStr}}
 {{- end}}
 )
 {{if .names -}}
diff --git a/generator/generator.go b/generator/generator.go
index 35e6094..38b02eb 100644
--- a/generator/generator.go
+++ b/generator/generator.go
@@ -99,6 +99,7 @@ func NewGenerator() *Generator {
 	funcs["unmapify"] = Unmapify
 	funcs["namify"] = Namify
 	funcs["offset"] = Offset
+	funcs["quote"] = strconv.Quote
 
 	g.t.Funcs(funcs)
 
@@ -447,8 +448,8 @@ func (g *Generator) parseEnum(ts *ast.TypeSpec) (*Enum, error) {
 							data = parsed
 							valueStr = rawName
 						}
-						if isQuoted(dataVal) {
-							valueStr = trimQuotes(dataVal)
+						if q := identifyQuoted(dataVal); q != "" {
+							valueStr = trimQuotes(q, dataVal)
 						}
 					} else if unsigned {
 						newData, err := strconv.ParseUint(dataVal, 0, 64)
@@ -495,18 +496,19 @@ func (g *Generator) parseEnum(ts *ast.TypeSpec) (*Enum, error) {
 	return enum, nil
 }
 
-func isQuoted(s string) bool {
+func identifyQuoted(s string) string {
 	s = strings.TrimSpace(s)
-	return (strings.HasPrefix(s, `"`) && strings.HasSuffix(s, `"`)) || (strings.HasPrefix(s, `'`) && strings.HasSuffix(s, `'`))
+	if strings.HasPrefix(s, `"`) && strings.HasSuffix(s, `"`) {
+		return `"`
+	}
+	if strings.HasPrefix(s, `'`) && strings.HasSuffix(s, `'`) {
+		return `'`
+	}
+	return ""
 }
 
-func trimQuotes(s string) string {
-	s = strings.TrimSpace(s)
-	for _, quote := range []string{`"`, `'`} {
-		s = strings.TrimPrefix(s, quote)
-		s = strings.TrimSuffix(s, quote)
-	}
-	return s
+func trimQuotes(q, s string) string {
+	return strings.TrimPrefix(strings.TrimSuffix(strings.TrimSpace(s), q), q)
 }
 
 func increment(d interface{}) interface{} {


Test patch:
diff --git a/generator/generator_test.go b/generator/generator_test.go
index fcae16c..9cad7c7 100644
--- a/generator/generator_test.go
+++ b/generator/generator_test.go
@@ -389,3 +389,54 @@ func TestQuotedStrings(t *testing.T) {
 		fmt.Println(string(output))
 	}
 }
+
+func TestStringWithSingleDoubleQuoteValue(t *testing.T) {
+	input := `package test
+	// ENUM(DoubleQuote='"')
+	type Char string
+	`
+	g := NewGenerator()
+	f, err := parser.ParseFile(g.fileSet, "TestRequiredErrors", input, parser.ParseComments)
+	assert.Nil(t, err, "Error parsing no struct input")
+
+	output, err := g.Generate(f)
+	assert.Nil(t, err, "Error generating formatted code")
+	assert.Contains(t, string(output), "CharDoubleQuote Char = \"\\\"\"")
+	if false { // Debugging statement
+		fmt.Println(string(output))
+	}
+}
+
+func TestStringWithSingleSingleQuoteValue(t *testing.T) {
+	input := `package test
+	// ENUM(SingleQuote="'")
+	type Char string
+	`
+	g := NewGenerator()
+	f, err := parser.ParseFile(g.fileSet, "TestRequiredErrors", input, parser.ParseComments)
+	assert.Nil(t, err, "Error parsing no struct input")
+
+	output, err := g.Generate(f)
+	assert.Nil(t, err, "Error generating formatted code")
+	assert.Contains(t, string(output), "CharSingleQuote Char = \"'\"")
+	if false { // Debugging statement
+		fmt.Println(string(output))
+	}
+}
+
+func TestStringWithSingleBacktickValue(t *testing.T) {
+	input := `package test
+	// ENUM(SingleQuote="` + "`" + `")
+	type Char string
+	`
+	g := NewGenerator()
+	f, err := parser.ParseFile(g.fileSet, "TestRequiredErrors", input, parser.ParseComments)
+	assert.Nil(t, err, "Error parsing no struct input")
+
+	output, err := g.Generate(f)
+	assert.Nil(t, err, "Error generating formatted code")
+	assert.Contains(t, string(output), "CharSingleQuote Char = \"`\"")
+	if false { // Debugging statement
+		fmt.Println(string(output))
+	}
+}