naming_strategy.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package extra
  2. import (
  3. "github.com/json-iterator/go"
  4. "strings"
  5. "unicode"
  6. )
  7. // SetNamingStrategy rename struct fields uniformly
  8. func SetNamingStrategy(translate func(string) string) {
  9. jsoniter.RegisterExtension(&namingStrategyExtension{jsoniter.DummyExtension{}, translate})
  10. }
  11. type namingStrategyExtension struct {
  12. jsoniter.DummyExtension
  13. translate func(string) string
  14. }
  15. func (extension *namingStrategyExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
  16. for _, binding := range structDescriptor.Fields {
  17. if unicode.IsLower(rune(binding.Field.Name()[0])) || binding.Field.Name()[0] == '_'{
  18. continue
  19. }
  20. tag, hastag := binding.Field.Tag().Lookup("json")
  21. if hastag {
  22. tagParts := strings.Split(tag, ",")
  23. if tagParts[0] == "-" {
  24. continue // hidden field
  25. }
  26. if tagParts[0] != "" {
  27. continue // field explicitly named
  28. }
  29. }
  30. binding.ToNames = []string{extension.translate(binding.Field.Name())}
  31. binding.FromNames = []string{extension.translate(binding.Field.Name())}
  32. }
  33. }
  34. // LowerCaseWithUnderscores one strategy to SetNamingStrategy for. It will change HelloWorld to hello_world.
  35. func LowerCaseWithUnderscores(name string) string {
  36. newName := []rune{}
  37. for i, c := range name {
  38. if i == 0 {
  39. newName = append(newName, unicode.ToLower(c))
  40. } else {
  41. if unicode.IsUpper(c) {
  42. newName = append(newName, '_')
  43. newName = append(newName, unicode.ToLower(c))
  44. } else {
  45. newName = append(newName, c)
  46. }
  47. }
  48. }
  49. return string(newName)
  50. }