package json import ( "encoding/json" "fmt" "git.loafle.net/commons_go/rpc/protocol" crp "git.loafle.net/commons_go/rpc/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 error `json:"error,omitempty"` ID interface{} `json:"id,omitempty"` } // ClientResponseCodec decodes and encodes a single request. type ClientResponseCodec struct { res *clientResponse err error } func (crc *ClientResponseCodec) ID() interface{} { return crc.res.ID } func (crc *ClientResponseCodec) Result(result interface{}) error { if nil == crc.err && nil != crc.res.Result { if err := json.Unmarshal(*crc.res.Result, result); nil != err { crc.err = &Error{ Code: crp.E_PARSE, Message: err.Error(), Data: crc.res.Result, } } } return crc.err } func (crc *ClientResponseCodec) Error() error { return crc.res.Error } func (crc *ClientResponseCodec) Notification() (protocol.ClientNotificationCodec, error) { if nil != crc.res.ID || nil == crc.res.Result { return nil, fmt.Errorf("RPC[JSON]: This is not notification") } noti := &clientNotification{} err := json.Unmarshal(*crc.res.Result, noti) if nil != err { return nil, err } return &ClientNotificationCodec{noti: noti, err: err}, nil } // newClientMessageCodec returns a new ClientMessageCodec. func newClientResponseCodec(buf []byte) (protocol.ClientResponseCodec, error) { res := &clientResponse{} err := json.Unmarshal(buf, res) if err != nil { err = &Error{ Code: crp.E_PARSE, Message: err.Error(), Data: res, } } if res.Version != Version { err = &Error{ Code: crp.E_INVALID_REQ, Message: "jsonrpc must be " + Version, Data: res, } } return &ClientResponseCodec{res: res, err: err}, nil }