package xjson import ( "encoding/json" "fmt" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" "reflect" ) func MustMarshal(data any) string { b, err := json.Marshal(data) if err != nil { return "" } return string(b) } 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 Marshal(v interface{}) ([]byte, error) { switch m := v.(type) { case json.Marshaler: return m.MarshalJSON() case proto.Message: return MarshalOptions.Marshal(m) default: return json.Marshal(m) } } func Unmarshal(data []byte, v interface{}) error { switch m := v.(type) { case json.Unmarshaler: return m.UnmarshalJSON(data) case proto.Message: return UnmarshalOptions.Unmarshal(data, m) default: rv := reflect.ValueOf(v) for rv := rv; rv.Kind() == reflect.Ptr; { if rv.IsNil() { rv.Set(reflect.New(rv.Type().Elem())) } rv = rv.Elem() } if m, ok := reflect.Indirect(rv).Interface().(proto.Message); ok { return UnmarshalOptions.Unmarshal(data, m) } return json.Unmarshal(data, m) } } func PrintData(a any) { b, _ := Marshal(a) fmt.Println(string(b)) }