github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/remote/json_serializer.go (about)

     1  package remote
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"reflect"
     7  
     8  	"github.com/gogo/protobuf/jsonpb"
     9  	"github.com/gogo/protobuf/proto"
    10  )
    11  
    12  type jsonSerializer struct {
    13  	jsonpb.Marshaler
    14  	jsonpb.Unmarshaler
    15  }
    16  
    17  func newJsonSerializer() Serializer {
    18  	return &jsonSerializer{
    19  		Marshaler: jsonpb.Marshaler{},
    20  		Unmarshaler: jsonpb.Unmarshaler{
    21  			AllowUnknownFields: true,
    22  		},
    23  	}
    24  }
    25  
    26  func (j *jsonSerializer) Serialize(msg interface{}) ([]byte, error) {
    27  	if message, ok := msg.(*JsonMessage); ok {
    28  		return []byte(message.Json), nil
    29  	} else if message, ok := msg.(proto.Message); ok {
    30  
    31  		str, err := j.Marshaler.MarshalToString(message)
    32  		if err != nil {
    33  			return nil, err
    34  		}
    35  
    36  		return []byte(str), nil
    37  	}
    38  	return nil, fmt.Errorf("msg must be proto.Message")
    39  }
    40  
    41  func (j *jsonSerializer) Deserialize(typeName string, b []byte) (interface{}, error) {
    42  	protoType := proto.MessageType(typeName)
    43  	if protoType == nil {
    44  		m := &JsonMessage{
    45  			TypeName: typeName,
    46  			Json:     string(b),
    47  		}
    48  		return m, nil
    49  	}
    50  	t := protoType.Elem()
    51  
    52  	intPtr := reflect.New(t)
    53  	instance, ok := intPtr.Interface().(proto.Message)
    54  	if ok {
    55  		r := bytes.NewReader(b)
    56  		j.Unmarshaler.Unmarshal(r, instance)
    57  
    58  		return instance, nil
    59  	}
    60  
    61  	return nil, fmt.Errorf("msg must be proto.Message")
    62  }
    63  
    64  func (j *jsonSerializer) GetTypeName(msg interface{}) (string, error) {
    65  	if message, ok := msg.(*JsonMessage); ok {
    66  		return message.TypeName, nil
    67  	} else if message, ok := msg.(proto.Message); ok {
    68  		typeName := proto.MessageName(message)
    69  
    70  		return typeName, nil
    71  	}
    72  
    73  	return "", fmt.Errorf("msg must be proto.Message")
    74  }