json.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package jsonpb
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "reflect"
  6. "github.com/gogo/protobuf/proto"
  7. "github.com/golang/protobuf/jsonpb"
  8. "github.com/go-kratos/kratos/v2/encoding"
  9. )
  10. // Name is the name registered for the json codec.
  11. const Name = "jsonpb"
  12. var jsonpbMarshaler *jsonpb.Marshaler
  13. func init() {
  14. jsonpbMarshaler = &jsonpb.Marshaler{
  15. EnumsAsInts: true,
  16. EmitDefaults: true,
  17. OrigName: true,
  18. }
  19. encoding.RegisterCodec(codec{})
  20. }
  21. // codec is a Codec implementation with json.
  22. type codec struct{}
  23. func (codec) Marshal(v interface{}) ([]byte, error) {
  24. if _, ok := v.(proto.Message); ok {
  25. var buf bytes.Buffer
  26. err := jsonpbMarshaler.Marshal(&buf, v.(proto.Message))
  27. if err != nil {
  28. return nil, err
  29. }
  30. return buf.Bytes(), nil
  31. }
  32. return json.Marshal(v)
  33. }
  34. func (codec) Unmarshal(data []byte, v interface{}) error {
  35. rv := reflect.ValueOf(v)
  36. for rv.Kind() == reflect.Ptr {
  37. if rv.IsNil() && rv.CanInterface() {
  38. rv.Set(reflect.New(rv.Type().Elem()))
  39. v = rv.Interface()
  40. }
  41. rv = rv.Elem()
  42. }
  43. return json.Unmarshal(data, v)
  44. }
  45. func (codec) Name() string {
  46. return Name
  47. }