package json import ( "encoding/json" "reflect" "github.com/go-kratos/kratos/v2/encoding" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" ) // Name is the name registered for the json codec. const Name = "json" var ( // MarshalOptions is a configurable JSON format marshaller. MarshalOptions = protojson.MarshalOptions{ EmitUnpopulated: true, } // UnmarshalOptions is a configurable JSON format parser. UnmarshalOptions = protojson.UnmarshalOptions{ DiscardUnknown: true, } ) func init() { encoding.RegisterCodec(codec{}) } // codec is a Codec implementation with json. type codec struct{} func (codec) Marshal(v interface{}) ([]byte, error) { if m, ok := v.(proto.Message); ok { return MarshalOptions.Marshal(m) } return json.Marshal(v) } func (codec) Unmarshal(data []byte, v interface{}) error { rv := reflect.ValueOf(v) for rv.Kind() == reflect.Ptr { if rv.IsNil() { rv.Set(reflect.New(rv.Type().Elem())) } rv = rv.Elem() } if m, ok := v.(proto.Message); ok { return UnmarshalOptions.Unmarshal(data, m) } else if m, ok := reflect.Indirect(reflect.ValueOf(v)).Interface().(proto.Message); ok { return UnmarshalOptions.Unmarshal(data, m) } return json.Unmarshal(data, v) } func (codec) Name() string { return Name }