1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//! This crate implements the structures as defined in the [JSON-RPC 2.0 Specification](https://www.jsonrpc.org/specification)
//!
//! # Requirements
//!
//! These requirements derived from the specification itself.
//!
//! - The "jsonrpc" field MUST be present in requests, responses, and notifications. Futhormore, the value of the "jsonrpc" field MUST be "2.0".
//! - The "id" field MUST contain a String, Number, or Null value in any request or response.
//! - The Null value for "id" in a request object is discouraged, as it's used for responses in which the original request id is unknown.
//! - The Number value for "id" SHOULD NOT contain fractional parts, as many decimal fractions cannot be represented exactly as binary fraction.
//! - The "method" field MUST contain a String in any request.
//! - The optional "params" field MUST be either an Object (by-name) or Array (by-position) IF the "params" are present in the request or notification.
//!
//! # Dependencies
//!
//! - **serde**: used for (de)serialization
//! - **serde_json**: used for JSON de(serialization) implementation
//! - **thiserror**: used for error reporting
//!
//! # Usage
//!
//! ## Requests
//!
//! You can easily build a JSON-RPC request:
//! ```rust
//! use jrpc_types::JsonRpcRequest;
//!
//! let data = vec![10, 293, 2, 193, 2];
//! let req = JsonRpcRequest::builder()
//! .method("sort")
//! .params(data)
//! .unwrap() // Serialization of parameters could fail, so you need to catch this.
//! .id(2)
//! .build();
//! ```
//!
//! Deserializing a request from a string is super easy:
//! ```rust
//! use jrpc_types::JsonRpcRequest;
//!
//! let data = r#"{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}"#;
//! match TryInto::<JsonRpcRequest>::try_into(data) {
//! Ok(req) => {
//! // .. do something ..
//! }
//! Err(e) => {
//! // .. handle error ..
//! }
//! }
//! ```
//!
//! ## Notifications
//!
//! JSON-RPC Notifications are pretty much Requests, without an ID... You can build Notifications like:
//! ```rust
//! use jrpc_types::JsonRpcNotification;
//!
//! let data = vec![10, 293, 2, 193, 2];
//! let req = JsonRpcNotification::builder()
//! .method("event")
//! .params(data)
//! .unwrap() // Serialization of parameters could fail, so you need to catch this.
//! .build();
//! ```
//!
//! Deserializing a notification from a string is super easy:
//! ```rust
//! use jrpc_types::JsonRpcNotification;
//!
//! let data = r#"{"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}"#;
//! match TryInto::<JsonRpcNotification>::try_into(data) {
//! Ok(req) => {
//! // .. do something ..
//! }
//! Err(e) => {
//! // .. handle error ..
//! }
//! }
//! ```
//!
//! ## Response
//!
//! A JSON-RPC response contains different fields depending on success or error.
//! There is also a select set of (code, message) pairs for errors that are defined in the spec.
//! The builder implementation makes it incredibly easy to build these responses.
//!
//! Success response (w/ optional data):
//! ```rust
//! use jrpc_types::JsonRpcResponse;
//!
//! let data = vec![10, 293, 2, 193, 2];
//! let req = JsonRpcResponse::builder()
//! .success()
//! .result(data)
//! .unwrap() // Serialization of parameters could fail, so you need to catch this.
//! .id(2)
//! .build();
//! ```
//!
//! Invalid request error:
//! ```rust
//! use jrpc_types::JsonRpcResponse;
//!
//! let data = vec![10, 293, 2, 193, 2];
//! let req = JsonRpcResponse::builder()
//! .error()
//! .invalid_request()
//! .id(2)
//! .build();
//! ```
//!
//! Custom Error:
//! ```rust
//! use jrpc_types::JsonRpcResponse;
//!
//! let data = vec![10, 293, 2, 193, 2];
//! let req = JsonRpcResponse::builder()
//! .error()
//! .code(-23)
//! .message("bad request man...")
//! .id(2)
//! .build();
//! ```
//!
//! **NOTE**: If you are processing a JsonRpcRequest and building a JsonRpcResponse, you can use &JsonRpcRequest in the id() builder function.
//! ```rust
//! use jrpc_types::{JsonRpcRequest, JsonRpcResponse};
//!
//! // Just for docs, creating this here.. assume you have this.
//! let req = JsonRpcRequest::builder()
//! .id(10)
//! .method("subtract")
//! .params_str("[5,2]")
//! .unwrap() // Serialization of parameters could fail, so you need to catch this.
//! .build();
//!
//! // ... process stuff ...
//!
//! let rsp = JsonRpcResponse::builder()
//! .id(&req)
//! .success()
//! .result(3)
//! .unwrap() // Serialization of parameters could fail, so you need to catch this.
//! .build();
//! ```
pub use Error as JsonRpcError;
pub use Notification as JsonRpcNotification;
pub use Request as JsonRpcRequest;
pub use Response as JsonRpcResponse;