package json import ( "encoding/json" "io" "math/rand" ) // ---------------------------------------------------------------------------- // Request and Response // ---------------------------------------------------------------------------- // clientRequest represents a JSON-RPC request sent by a client. type clientRequest struct { // JSON-RPC protocol. Version string `json:"jsonrpc"` // A String containing the name of the method to be invoked. Method string `json:"method"` // Object to pass as request parameter to the method. Params interface{} `json:"params"` // The request id. This can be of any type. It is used to match the // response with the request that it is replying to. ID uint64 `json:"id"` } // clientResponse represents a JSON-RPC response returned to a client. type clientResponse struct { Version string `json:"jsonrpc"` Result *json.RawMessage `json:"result"` Error *json.RawMessage `json:"error"` } // EncodeClientRequest encodes parameters for a JSON-RPC client request. func EncodeClientRequest(method string, args interface{}) ([]byte, error) { c := &clientRequest{ Version: "2.0", Method: method, Params: args, ID: uint64(rand.Int63()), } return json.Marshal(c) } // EncodeClientNotify encodes parameters for a JSON-RPC client notification. func EncodeClientNotify(method string, args interface{}) ([]byte, error) { c := &clientRequest{ Version: "2.0", Method: method, Params: args, } return json.Marshal(c) } // DecodeClientResponse decodes the response body of a client request into // the interface reply. func DecodeClientResponse(r io.Reader, reply interface{}) error { var c clientResponse if err := json.NewDecoder(r).Decode(&c); err != nil { return err } if c.Error != nil { jsonErr := &Error{} if err := json.Unmarshal(*c.Error, jsonErr); err != nil { return &Error{ Code: E_SERVER, Message: string(*c.Error), } } return jsonErr } if c.Result == nil { return ErrNullResult } return json.Unmarshal(*c.Result, reply) }