package json import ( "encoding/json" "fmt" "git.loafle.net/overflow/rpc-go/protocol" ) // ---------------------------------------------------------------------------- // ClientResponseCodec // ---------------------------------------------------------------------------- // clientResponse represents a JSON-RPC response returned to a client. type clientResponse struct { Version string `json:"jsonrpc"` Result *json.RawMessage `json:"result,omitempty"` Error *protocol.Error `json:"error,omitempty"` ID interface{} `json:"id,omitempty"` } // ClientResponseCodec decodes and encodes a single request. type ClientResponseCodec struct { res *clientResponse } func (crc *ClientResponseCodec) ID() interface{} { return crc.res.ID } func (crc *ClientResponseCodec) Result(result interface{}) error { if nil == crc.res.Error && nil != crc.res.Result { if err := json.Unmarshal(*crc.res.Result, &result); nil != err { return err } return nil } return fmt.Errorf("There is no result") } func (crc *ClientResponseCodec) Error() *protocol.Error { return crc.res.Error } func (crc *ClientResponseCodec) IsNotification() bool { if nil == crc.res.ID && nil != crc.res.Result { return true } return false } func (crc *ClientResponseCodec) Notification() (protocol.ClientNotificationCodec, error) { if nil != crc.res.ID || nil == crc.res.Result { return nil, fmt.Errorf("This is not notification") } noti := &clientNotification{} err := json.Unmarshal(*crc.res.Result, noti) if nil != err { return nil, err } return &ClientNotificationCodec{noti: noti}, nil } // newClientMessageCodec returns a new ClientMessageCodec. func newClientResponseCodec(buf []byte) (protocol.ClientResponseCodec, error) { res := &clientResponse{} err := json.Unmarshal(buf, res) if err != nil { return nil, fmt.Errorf("Cannot unmarshal response [%s] err: %v", string(buf), err) } if res.Version != Version { return nil, fmt.Errorf("The protocol version of response[%s] is not %s", string(buf), Version) } return &ClientResponseCodec{res: res}, nil }