github.com/songzhibin97/gkit@v1.2.13/coding/json/json.go (about)

     1  package json
     2  
     3  import (
     4  	"reflect"
     5  
     6  	json "github.com/json-iterator/go"
     7  
     8  	"github.com/songzhibin97/gkit/coding"
     9  	"google.golang.org/protobuf/encoding/protojson"
    10  	"google.golang.org/protobuf/proto"
    11  )
    12  
    13  const Name = "json"
    14  
    15  var (
    16  	MarshalOptions = protojson.MarshalOptions{
    17  		EmitUnpopulated: true,
    18  		UseProtoNames:   true,
    19  	}
    20  
    21  	UnmarshalOptions = protojson.UnmarshalOptions{
    22  		DiscardUnknown: true,
    23  	}
    24  )
    25  
    26  func init() {
    27  	_ = coding.RegisterCode(code{})
    28  }
    29  
    30  type code struct{}
    31  
    32  func (c code) Marshal(v interface{}) ([]byte, error) {
    33  	if m, ok := v.(proto.Message); ok {
    34  		return MarshalOptions.Marshal(m)
    35  	}
    36  	return json.Marshal(v)
    37  }
    38  
    39  func (c code) Unmarshal(data []byte, v interface{}) error {
    40  	rv := reflect.ValueOf(v)
    41  	for rv.Kind() == reflect.Ptr {
    42  		if rv.IsNil() {
    43  			rv.Set(reflect.New(rv.Type().Elem()))
    44  		}
    45  		rv = rv.Elem()
    46  	}
    47  	if m, ok := v.(proto.Message); ok {
    48  		return UnmarshalOptions.Unmarshal(data, m)
    49  	} else if m, ok := reflect.Indirect(reflect.ValueOf(v)).Interface().(proto.Message); ok {
    50  		return UnmarshalOptions.Unmarshal(data, m)
    51  	}
    52  	return json.Unmarshal(data, v)
    53  }
    54  
    55  func (c code) Name() string {
    56  	return Name
    57  }