Last active
February 28, 2022 19:23
-
-
Save gwennlbh/ad7750f562a319f81ccc05d08512a24b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ( | |
"strings" | |
jsoniter "github.com/json-iterator/go" | |
"unicode" | |
) | |
// Usage: put | |
// | |
// json := jsoniter.ConfigFastest | |
// setJSONNamingStrategy(lowerCaseWithUnderscore) | |
// | |
// before marshaling data with json.Marshal(...) | |
// setJSONNamingStrategy rename struct fields uniformly. | |
func setJSONNamingStrategy(translate func(string) string) { | |
jsoniter.RegisterExtension(&namingStrategyExtension{jsoniter.DummyExtension{}, translate}) | |
} | |
type namingStrategyExtension struct { | |
jsoniter.DummyExtension | |
translate func(string) string | |
} | |
func (extension *namingStrategyExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) { | |
for _, binding := range structDescriptor.Fields { | |
if unicode.IsLower(rune(binding.Field.Name()[0])) || binding.Field.Name()[0] == '_' { | |
continue | |
} | |
tag, hastag := binding.Field.Tag().Lookup("json") | |
if hastag { | |
tagParts := strings.Split(tag, ",") | |
if tagParts[0] == "-" { | |
continue // hidden field | |
} | |
if tagParts[0] != "" { | |
continue // field explicitly named | |
} | |
} | |
binding.ToNames = []string{extension.translate(binding.Field.Name())} | |
binding.FromNames = []string{extension.translate(binding.Field.Name())} | |
} | |
} | |
// lowerCaseWithUnderscores one strategy to SetNamingStrategy for. It will change HelloWorld to hello_world. | |
func lowerCaseWithUnderscores(name string) string { | |
// Handle acronyms | |
if isAllUpper(name) { | |
return strings.ToLower(name) | |
} | |
newName := []rune{} | |
for i, c := range name { | |
if i == 0 { | |
newName = append(newName, unicode.ToLower(c)) | |
} else { | |
if c == ' ' { | |
newName = append(newName, '_') | |
} else if unicode.IsUpper(c) { | |
newName = append(newName, '_') | |
newName = append(newName, unicode.ToLower(c)) | |
} else { | |
newName = append(newName, c) | |
} | |
} | |
} | |
return string(newName) | |
} | |
func isAllUpper(s string) bool { | |
for _, c := range s { | |
if !unicode.IsUpper(c) { | |
return false | |
} | |
} | |
return true | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment