140 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
// Copyright 2018 The Go Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style
 | 
						|
// license that can be found in the LICENSE file.
 | 
						|
 | 
						|
package jsonrpc2
 | 
						|
 | 
						|
import (
 | 
						|
	"encoding/json"
 | 
						|
	"fmt"
 | 
						|
	"strconv"
 | 
						|
)
 | 
						|
 | 
						|
// this file contains the go forms of the wire specification
 | 
						|
// see http://www.jsonrpc.org/specification for details
 | 
						|
 | 
						|
const (
 | 
						|
	// CodeUnknownError should be used for all non coded errors.
 | 
						|
	CodeUnknownError = -32001
 | 
						|
	// CodeParseError is used when invalid JSON was received by the server.
 | 
						|
	CodeParseError = -32700
 | 
						|
	//CodeInvalidRequest is used when the JSON sent is not a valid Request object.
 | 
						|
	CodeInvalidRequest = -32600
 | 
						|
	// CodeMethodNotFound should be returned by the handler when the method does
 | 
						|
	// not exist / is not available.
 | 
						|
	CodeMethodNotFound = -32601
 | 
						|
	// CodeInvalidParams should be returned by the handler when method
 | 
						|
	// parameter(s) were invalid.
 | 
						|
	CodeInvalidParams = -32602
 | 
						|
	// CodeInternalError is not currently returned but defined for completeness.
 | 
						|
	CodeInternalError = -32603
 | 
						|
)
 | 
						|
 | 
						|
// Request is sent to a server to represent a Call or Notify operaton.
 | 
						|
type Request struct {
 | 
						|
	// VersionTag is always encoded as the string "2.0"
 | 
						|
	VersionTag VersionTag `json:"jsonrpc"`
 | 
						|
	// Method is a string containing the method name to invoke.
 | 
						|
	Method string `json:"method"`
 | 
						|
	// Params is either a struct or an array with the parameters of the method.
 | 
						|
	Params *json.RawMessage `json:"params,omitempty"`
 | 
						|
	// The id of this request, used to tie the Response back to the request.
 | 
						|
	// Will be either a string or a number. If not set, the Request is a notify,
 | 
						|
	// and no response is possible.
 | 
						|
	ID *ID `json:"id,omitempty"`
 | 
						|
}
 | 
						|
 | 
						|
// Response is a reply to a Request.
 | 
						|
// It will always have the ID field set to tie it back to a request, and will
 | 
						|
// have either the Result or Error fields set depending on whether it is a
 | 
						|
// success or failure response.
 | 
						|
type Response struct {
 | 
						|
	// VersionTag is always encoded as the string "2.0"
 | 
						|
	VersionTag VersionTag `json:"jsonrpc"`
 | 
						|
	// Result is the response value, and is required on success.
 | 
						|
	Result *json.RawMessage `json:"result,omitempty"`
 | 
						|
	// Error is a structured error response if the call fails.
 | 
						|
	Error *Error `json:"error,omitempty"`
 | 
						|
	// ID must be set and is the identifier of the Request this is a response to.
 | 
						|
	ID *ID `json:"id,omitempty"`
 | 
						|
}
 | 
						|
 | 
						|
// Error represents a structured error in a Response.
 | 
						|
type Error struct {
 | 
						|
	// Code is an error code indicating the type of failure.
 | 
						|
	Code int64 `json:"code"`
 | 
						|
	// Message is a short description of the error.
 | 
						|
	Message string `json:"message"`
 | 
						|
	// Data is optional structured data containing additional information about the error.
 | 
						|
	Data *json.RawMessage `json:"data"`
 | 
						|
}
 | 
						|
 | 
						|
// VersionTag is a special 0 sized struct that encodes as the jsonrpc version
 | 
						|
// tag.
 | 
						|
// It will fail during decode if it is not the correct version tag in the
 | 
						|
// stream.
 | 
						|
type VersionTag struct{}
 | 
						|
 | 
						|
// ID is a Request identifier.
 | 
						|
// Only one of either the Name or Number members will be set, using the
 | 
						|
// number form if the Name is the empty string.
 | 
						|
type ID struct {
 | 
						|
	Name   string
 | 
						|
	Number int64
 | 
						|
}
 | 
						|
 | 
						|
// IsNotify returns true if this request is a notification.
 | 
						|
func (r *Request) IsNotify() bool {
 | 
						|
	return r.ID == nil
 | 
						|
}
 | 
						|
 | 
						|
func (err *Error) Error() string {
 | 
						|
	if err == nil {
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
	return err.Message
 | 
						|
}
 | 
						|
 | 
						|
func (VersionTag) MarshalJSON() ([]byte, error) {
 | 
						|
	return json.Marshal("2.0")
 | 
						|
}
 | 
						|
 | 
						|
func (VersionTag) UnmarshalJSON(data []byte) error {
 | 
						|
	version := ""
 | 
						|
	if err := json.Unmarshal(data, &version); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if version != "2.0" {
 | 
						|
		return fmt.Errorf("Invalid RPC version %v", version)
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// String returns a string representation of the ID.
 | 
						|
// The representation is non ambiguous, string forms are quoted, number forms
 | 
						|
// are preceded by a #
 | 
						|
func (id *ID) String() string {
 | 
						|
	if id == nil {
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
	if id.Name != "" {
 | 
						|
		return strconv.Quote(id.Name)
 | 
						|
	}
 | 
						|
	return "#" + strconv.FormatInt(id.Number, 10)
 | 
						|
}
 | 
						|
 | 
						|
func (id *ID) MarshalJSON() ([]byte, error) {
 | 
						|
	if id.Name != "" {
 | 
						|
		return json.Marshal(id.Name)
 | 
						|
	}
 | 
						|
	return json.Marshal(id.Number)
 | 
						|
}
 | 
						|
 | 
						|
func (id *ID) UnmarshalJSON(data []byte) error {
 | 
						|
	*id = ID{}
 | 
						|
	if err := json.Unmarshal(data, &id.Number); err == nil {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	return json.Unmarshal(data, &id.Name)
 | 
						|
}
 |