81 lines
2.1 KiB
Go
81 lines
2.1 KiB
Go
|
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
|
||
|
}
|