...
1
2
3
4
5 package jsonrpc2
6
7 import (
8 "encoding/json"
9 "fmt"
10 )
11
12
13
14
15 var (
16
17 ErrUnknown = NewError(-32001, "JSON RPC unknown error")
18
19 ErrParse = NewError(-32700, "JSON RPC parse error")
20
21 ErrInvalidRequest = NewError(-32600, "JSON RPC invalid request")
22
23
24 ErrMethodNotFound = NewError(-32601, "JSON RPC method not found")
25
26
27 ErrInvalidParams = NewError(-32602, "JSON RPC invalid params")
28
29 ErrInternal = NewError(-32603, "JSON RPC internal error")
30
31
32
33 ErrServerOverloaded = NewError(-32000, "JSON RPC overloaded")
34 )
35
36
37 type wireRequest struct {
38
39 VersionTag wireVersionTag `json:"jsonrpc"`
40
41 Method string `json:"method"`
42
43 Params *json.RawMessage `json:"params,omitempty"`
44
45
46
47 ID *ID `json:"id,omitempty"`
48 }
49
50
51
52
53
54 type wireResponse struct {
55
56 VersionTag wireVersionTag `json:"jsonrpc"`
57
58 Result *json.RawMessage `json:"result,omitempty"`
59
60 Error *WireError `json:"error,omitempty"`
61
62 ID *ID `json:"id,omitempty"`
63 }
64
65
66
67 type wireCombined struct {
68 VersionTag wireVersionTag `json:"jsonrpc"`
69 ID *ID `json:"id,omitempty"`
70 Method string `json:"method"`
71 Params *json.RawMessage `json:"params,omitempty"`
72 Result *json.RawMessage `json:"result,omitempty"`
73 Error *WireError `json:"error,omitempty"`
74 }
75
76
77 type WireError struct {
78
79 Code int64 `json:"code"`
80
81 Message string `json:"message"`
82
83 Data *json.RawMessage `json:"data,omitempty"`
84 }
85
86
87
88
89
90 type wireVersionTag struct{}
91
92
93 type ID struct {
94 name string
95 number int64
96 }
97
98 func NewError(code int64, message string) error {
99 return &WireError{
100 Code: code,
101 Message: message,
102 }
103 }
104
105 func (err *WireError) Error() string {
106 return err.Message
107 }
108
109 func (wireVersionTag) MarshalJSON() ([]byte, error) {
110 return json.Marshal("2.0")
111 }
112
113 func (wireVersionTag) UnmarshalJSON(data []byte) error {
114 version := ""
115 if err := json.Unmarshal(data, &version); err != nil {
116 return err
117 }
118 if version != "2.0" {
119 return fmt.Errorf("invalid RPC version %v", version)
120 }
121 return nil
122 }
123
124
125 func NewIntID(v int64) ID { return ID{number: v} }
126
127
128 func NewStringID(v string) ID { return ID{name: v} }
129
130
131
132
133 func (id ID) Format(f fmt.State, r rune) {
134 numF, strF := `%d`, `%s`
135 if r == 'q' {
136 numF, strF = `#%d`, `%q`
137 }
138 switch {
139 case id.name != "":
140 fmt.Fprintf(f, strF, id.name)
141 default:
142 fmt.Fprintf(f, numF, id.number)
143 }
144 }
145
146 func (id *ID) MarshalJSON() ([]byte, error) {
147 if id.name != "" {
148 return json.Marshal(id.name)
149 }
150 return json.Marshal(id.number)
151 }
152
153 func (id *ID) UnmarshalJSON(data []byte) error {
154 *id = ID{}
155 if err := json.Unmarshal(data, &id.number); err == nil {
156 return nil
157 }
158 return json.Unmarshal(data, &id.name)
159 }
160
View as plain text