Merge pull request #125 from noisyscanner/master

Add lowerCamelCase naming strategy
This commit is contained in:
Vasily Romanov
2017-06-22 11:53:38 +03:00
committed by GitHub
5 changed files with 103 additions and 0 deletions
+2
View File
@@ -49,6 +49,8 @@ Usage of easyjson:
process the whole package instead of just the given file
-snake_case
use snake_case names instead of CamelCase by default
-lower_camel_case
use lowerCamelCase instead of CamelCase by default
-stubs
only generate stubs for marshaler/unmarshaler funcs
```
+4
View File
@@ -24,6 +24,7 @@ type Generator struct {
NoStdMarshalers bool
SnakeCase bool
LowerCamelCase bool
OmitEmpty bool
OutName string
@@ -110,6 +111,9 @@ func (g *Generator) writeMain() (path string, err error) {
if g.SnakeCase {
fmt.Fprintln(f, " g.UseSnakeCase()")
}
if g.LowerCamelCase {
fmt.Fprintln(f, " g.UseLowerCamelCase()")
}
if g.OmitEmpty {
fmt.Fprintln(f, " g.OmitEmpty()")
}
+2
View File
@@ -18,6 +18,7 @@ import (
var buildTags = flag.String("build_tags", "", "build tags to add to generated file")
var snakeCase = flag.Bool("snake_case", false, "use snake_case names instead of CamelCase by default")
var lowerCamelCase = flag.Bool("lower_camel_case", false, "use lowerCamelCase names instead of CamelCase by default")
var noStdMarshalers = flag.Bool("no_std_marshalers", false, "don't generate MarshalJSON/UnmarshalJSON funcs")
var omitEmpty = flag.Bool("omit_empty", false, "omit empty fields by default")
var allStructs = flag.Bool("all", false, "generate marshaler/unmarshalers for all structs in a file")
@@ -59,6 +60,7 @@ func generate(fname string) (err error) {
PkgName: p.PkgName,
Types: p.StructNames,
SnakeCase: *snakeCase,
LowerCamelCase: *lowerCamelCase,
NoStdMarshalers: *noStdMarshalers,
OmitEmpty: *omitEmpty,
LeaveTemps: *leaveTemps,
+73
View File
@@ -99,6 +99,11 @@ func (g *Generator) UseSnakeCase() {
g.fieldNamer = SnakeCaseFieldNamer{}
}
// UseLowerCamelCase sets lowerCamelCase field naming strategy.
func (g *Generator) UseLowerCamelCase() {
g.fieldNamer = LowerCamelCaseFieldNamer{}
}
// NoStdMarshalers instructs not to generate standard MarshalJSON/UnmarshalJSON
// methods (only the custom interface).
func (g *Generator) NoStdMarshalers() {
@@ -374,6 +379,74 @@ func (DefaultFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructField)
}
}
// LowerCamelCaseFieldNamer
type LowerCamelCaseFieldNamer struct {}
func isLower(b byte) bool {
return b <= 122 && b >= 97
}
func isUpper(b byte) bool {
return b >= 65 && b <= 90
}
func isNumeric(b byte) bool {
return b >= 48 && b <= 57
}
// convert HTTPRestClient to httpRestClient
func lowerFirst(s string) string {
if s == "" {
return ""
}
str := ""
strlen := len(s)
/**
Loop each char
If is uppercase:
If is first char, LOWER it
If the following char is lower, LEAVE it
If the following char is upper OR numeric, LOWER it
If is the end of string, LEAVE it
Else lowercase
*/
foundLower := false
for i := range s {
ch := s[i]
if isUpper(ch) {
if i == 0 {
str += string(ch + 32)
} else if !foundLower { // Currently just a stream of capitals, eg JSONRESTS[erver]
if strlen > (i+1) && isLower(s[i+1]) {
// Next char is lower, keep this a capital
str += string(ch)
} else {
// Either at end of string or next char is capital
str += string(ch + 32)
}
} else {
str += string(ch)
}
} else {
foundLower = true
str += string(ch)
}
}
return str
}
func (LowerCamelCaseFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructField) string {
jsonName := strings.Split(f.Tag.Get("json"), ",")[0]
if jsonName != "" {
return jsonName
} else {
return lowerFirst(f.Name)
}
}
// SnakeCaseFieldNamer implements CamelCase to snake_case conversion for fields names.
type SnakeCaseFieldNamer struct{}
+22
View File
@@ -28,6 +28,28 @@ func TestCamelToSnake(t *testing.T) {
}
}
func TestCamelToLowerCamel(t *testing.T) {
for i, test := range []struct {
In, Out string
}{
{"", ""},
{"A", "a"},
{"SimpleExample", "simpleExample"},
{"internalField", "internalField"},
{"SomeHTTPStuff", "someHTTPStuff"},
{"WriteJSON", "writeJSON"},
{"HTTP2Server", "http2Server"},
{"JSONHTTPRPCServer", "jsonhttprpcServer"}, // nothing can be done here without a dictionary
} {
got := lowerFirst(test.In)
if got != test.Out {
t.Errorf("[%d] lowerFirst(%s) = %s; want %s", i, test.In, got, test.Out)
}
}
}
func TestJoinFunctionNameParts(t *testing.T) {
for i, test := range []struct {
keepFirst bool