Skip to content

Commit

Permalink
feat: Add -casesensitive flag
Browse files Browse the repository at this point in the history
  • Loading branch information
gabe565 committed Oct 11, 2024
1 parent bcbe617 commit fb1078c
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 42 deletions.
10 changes: 6 additions & 4 deletions enumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (g *Generator) buildAltStringValuesMethod(typeName string) {
g.Printf(altStringValuesMethod, typeName)
}

func (g *Generator) buildBasicExtras(runs [][]Value, typeName string, runsThreshold int) {
func (g *Generator) buildBasicExtras(runs [][]Value, typeName string, runsThreshold int, caseSensitive bool) {
// At this moment, either "g.declareIndexAndNameVars()" or "g.declareNameVars()" has been called

// Print the slice of values
Expand All @@ -83,7 +83,7 @@ func (g *Generator) buildBasicExtras(runs [][]Value, typeName string, runsThresh
g.Printf("}\n\n")

// Print the map between name and value
g.printValueMap(runs, typeName, runsThreshold)
g.printValueMap(runs, typeName, runsThreshold, caseSensitive)

// Print the slice of names
g.printNamesSlice(runs, typeName, runsThreshold)
Expand All @@ -99,7 +99,7 @@ func (g *Generator) buildBasicExtras(runs [][]Value, typeName string, runsThresh
}
}

func (g *Generator) printValueMap(runs [][]Value, typeName string, runsThreshold int) {
func (g *Generator) printValueMap(runs [][]Value, typeName string, runsThreshold int, caseSensitive bool) {
thereAreRuns := len(runs) > 1 && len(runs) <= runsThreshold
g.Printf("\nvar _%sNameToValueMap = map[string]%s{\n", typeName, typeName)

Expand All @@ -115,7 +115,9 @@ func (g *Generator) printValueMap(runs [][]Value, typeName string, runsThreshold

for _, value := range values {
g.Printf("\t_%sName%s[%d:%d]: %s,\n", typeName, runID, n, n+len(value.name), value.originalName)
g.Printf("\t_%sLowerName%s[%d:%d]: %s,\n", typeName, runID, n, n+len(value.name), value.originalName)
if !caseSensitive {
g.Printf("\t_%sLowerName%s[%d:%d]: %s,\n", typeName, runID, n, n+len(value.name), value.originalName)
}
n += len(value.name)
}
}
Expand Down
28 changes: 14 additions & 14 deletions golden_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,45 +315,45 @@ 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 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, caseSensitive bool,
trimPrefix string, prefix string) {

var g Generator
Expand Down Expand Up @@ -382,7 +382,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, caseSensitive)
got := string(g.format())
if got != loadGolden(test.name) {
// Use this to help build a golden text when changes are needed
Expand Down
56 changes: 32 additions & 24 deletions stringer.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ var (
trimPrefix = flag.String("trimprefix", "", "transform each item name by removing a prefix or comma separated list of prefixes. 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")
caseSensitive = flag.Bool("casesensitive", false, "preserve case when creating a value from a string")
)

var comments arrayFlags
Expand Down Expand Up @@ -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, *caseSensitive)
}

// Format the output.
Expand Down Expand Up @@ -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,
caseSensitive bool) {
values := make([]Value, 0, 100)
for _, file := range g.pkg.files {
file.lineComment = lineComment
Expand Down Expand Up @@ -456,19 +458,19 @@ func (g *Generator) generate(typeName string,
const runsThreshold = 10
switch {
case len(runs) == 1:
g.buildOneRun(runs, typeName)
g.buildOneRun(runs, typeName, caseSensitive)
case len(runs) <= runsThreshold:
g.buildMultipleRuns(runs, typeName)
g.buildMultipleRuns(runs, typeName, caseSensitive)
default:
g.buildMap(runs, typeName)
g.buildMap(runs, typeName, caseSensitive)
}
if includeValuesMethod {
g.buildAltStringValuesMethod(typeName)
}

g.buildNoOpOrderChangeDetect(runs, typeName)

g.buildBasicExtras(runs, typeName, runsThreshold)
g.buildBasicExtras(runs, typeName, runsThreshold, caseSensitive)
if includeJSON {
g.buildJSONMethods(runs, typeName, runsThreshold)
}
Expand Down Expand Up @@ -663,14 +665,16 @@ func usize(n int) int {

// declareIndexAndNameVars declares the index slices and concatenated names
// strings representing the runs of values.
func (g *Generator) declareIndexAndNameVars(runs [][]Value, typeName string) {
func (g *Generator) declareIndexAndNameVars(runs [][]Value, typeName string, caseSensitive bool) {
var indexes, names []string
for i, run := range runs {
index, n := g.createIndexAndNameDecl(run, typeName, fmt.Sprintf("_%d", i))
indexes = append(indexes, index)
names = append(names, n)
_, n = g.createLowerIndexAndNameDecl(run, typeName, fmt.Sprintf("_%d", i))
names = append(names, n)
if !caseSensitive {
_, n = g.createLowerIndexAndNameDecl(run, typeName, fmt.Sprintf("_%d", i))
names = append(names, n)
}
}
g.Printf("const (\n")
for _, n := range names {
Expand All @@ -685,12 +689,14 @@ func (g *Generator) declareIndexAndNameVars(runs [][]Value, typeName string) {
}

// declareIndexAndNameVar is the single-run version of declareIndexAndNameVars
func (g *Generator) declareIndexAndNameVar(run []Value, typeName string) {
func (g *Generator) declareIndexAndNameVar(run []Value, typeName string, caseSensitive bool) {
index, n := g.createIndexAndNameDecl(run, typeName, "")
g.Printf("const %s\n", n)
g.Printf("var %s\n", index)
index, n = g.createLowerIndexAndNameDecl(run, typeName, "")
g.Printf("const %s\n", n)
if !caseSensitive {
index, n = g.createLowerIndexAndNameDecl(run, typeName, "")
g.Printf("const %s\n", n)
}
//g.Printf("var %s\n", index)
}

Expand Down Expand Up @@ -739,28 +745,30 @@ func (g *Generator) createIndexAndNameDecl(run []Value, typeName string, suffix
}

// declareNameVars declares the concatenated names string representing all the values in the runs.
func (g *Generator) declareNameVars(runs [][]Value, typeName string, suffix string) {
func (g *Generator) declareNameVars(runs [][]Value, typeName string, suffix string, caseSensitive bool) {
g.Printf("const _%sName%s = \"", typeName, suffix)
for _, run := range runs {
for i := range run {
g.Printf("%s", run[i].name)
}
}
g.Printf("\"\n")
g.Printf("const _%sLowerName%s = \"", typeName, suffix)
for _, run := range runs {
for i := range run {
g.Printf("%s", strings.ToLower(run[i].name))
if !caseSensitive {
g.Printf("const _%sLowerName%s = \"", typeName, suffix)
for _, run := range runs {
for i := range run {
g.Printf("%s", strings.ToLower(run[i].name))
}
}
g.Printf("\"\n")
}
g.Printf("\"\n")
}

// buildOneRun generates the variables and String method for a single run of contiguous values.
func (g *Generator) buildOneRun(runs [][]Value, typeName string) {
func (g *Generator) buildOneRun(runs [][]Value, typeName string, caseSensitive bool) {
values := runs[0]
g.Printf("\n")
g.declareIndexAndNameVar(values, typeName)
g.declareIndexAndNameVar(values, typeName, caseSensitive)
// The generated code is simple enough to write as a Printf format.
lessThanZero := ""
if values[0].signed {
Expand Down Expand Up @@ -801,9 +809,9 @@ const stringOneRunWithOffset = `func (i %[1]s) String() string {

// buildMultipleRuns generates the variables and String method for multiple runs of contiguous values.
// For this pattern, a single Printf format won't do.
func (g *Generator) buildMultipleRuns(runs [][]Value, typeName string) {
func (g *Generator) buildMultipleRuns(runs [][]Value, typeName string, caseSensitive bool) {
g.Printf("\n")
g.declareIndexAndNameVars(runs, typeName)
g.declareIndexAndNameVars(runs, typeName, caseSensitive)
g.Printf("func (i %s) String() string {\n", typeName)
g.Printf("\tswitch {\n")
for i, values := range runs {
Expand All @@ -827,9 +835,9 @@ func (g *Generator) buildMultipleRuns(runs [][]Value, typeName string) {

// buildMap handles the case where the space is so sparse a map is a reasonable fallback.
// It's a rare situation but has simple code.
func (g *Generator) buildMap(runs [][]Value, typeName string) {
func (g *Generator) buildMap(runs [][]Value, typeName string, caseSensitive bool) {
g.Printf("\n")
g.declareNameVars(runs, typeName, "")
g.declareNameVars(runs, typeName, "", caseSensitive)
g.Printf("\nvar _%sMap = map[%s]string{\n", typeName, typeName)
n := 0
for _, values := range runs {
Expand Down

0 comments on commit fb1078c

Please sign in to comment.