naming_strategy.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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. tag, hastag := binding.Field.Tag().Lookup("json")
  18. if hastag {
  19. tagParts := strings.Split(tag, ",")
  20. if tagParts[0] == "-" {
  21. continue // hidden field
  22. }
  23. if tagParts[0] != "" {
  24. continue // field explicitly named
  25. }
  26. }
  27. binding.ToNames = []string{extension.translate(binding.Field.Name())}
  28. binding.FromNames = []string{extension.translate(binding.Field.Name())}
  29. }
  30. }
  31. // LowerCaseWithUnderscores one strategy to SetNamingStrategy for. It will change HelloWorld to hello_world.
  32. func LowerCaseWithUnderscores(name string) string {
  33. newName := []rune{}
  34. for i, c := range name {
  35. if i == 0 {
  36. newName = append(newName, unicode.ToLower(c))
  37. } else {
  38. if unicode.IsUpper(c) {
  39. newName = append(newName, '_')
  40. newName = append(newName, unicode.ToLower(c))
  41. } else {
  42. newName = append(newName, c)
  43. }
  44. }
  45. }
  46. return string(newName)
  47. }