privat_fields.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package extra
  2. import (
  3. "github.com/json-iterator/go"
  4. "strings"
  5. "unicode"
  6. )
  7. // SupportPrivateFields include private fields when encoding/decoding
  8. func SupportPrivateFields() {
  9. jsoniter.RegisterExtension(&privateFieldsExtension{})
  10. }
  11. type privateFieldsExtension struct {
  12. jsoniter.DummyExtension
  13. }
  14. func (extension *privateFieldsExtension) UpdateStructDescriptor(structDescriptor *jsoniter.StructDescriptor) {
  15. for _, binding := range structDescriptor.Fields {
  16. isPrivate := unicode.IsLower(rune(binding.Field.Name()[0]))
  17. if isPrivate {
  18. tag, hastag := binding.Field.Tag().Lookup("json")
  19. if !hastag {
  20. binding.FromNames = []string{binding.Field.Name()}
  21. binding.ToNames = []string{binding.Field.Name()}
  22. continue
  23. }
  24. tagParts := strings.Split(tag, ",")
  25. names := calcFieldNames(binding.Field.Name(), tagParts[0], tag)
  26. binding.FromNames = names
  27. binding.ToNames = names
  28. }
  29. }
  30. }
  31. func calcFieldNames(originalFieldName string, tagProvidedFieldName string, wholeTag string) []string {
  32. // ignore?
  33. if wholeTag == "-" {
  34. return []string{}
  35. }
  36. // rename?
  37. var fieldNames []string
  38. if tagProvidedFieldName == "" {
  39. fieldNames = []string{originalFieldName}
  40. } else {
  41. fieldNames = []string{tagProvidedFieldName}
  42. }
  43. // private?
  44. isNotExported := unicode.IsLower(rune(originalFieldName[0]))
  45. if isNotExported {
  46. fieldNames = []string{}
  47. }
  48. return fieldNames
  49. }