jsonrpsee_core/traits.rs
1// Copyright 2019-2021 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any
4// person obtaining a copy of this software and associated
5// documentation files (the "Software"), to deal in the
6// Software without restriction, including without
7// limitation the rights to use, copy, modify, merge,
8// publish, distribute, sublicense, and/or sell copies of
9// the Software, and to permit persons to whom the Software
10// is furnished to do so, subject to the following
11// conditions:
12//
13// The above copyright notice and this permission notice
14// shall be included in all copies or substantial portions
15// of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25// DEALINGS IN THE SOFTWARE.
26
27use jsonrpsee_types::SubscriptionId;
28use serde::Serialize;
29use serde_json::value::RawValue;
30
31/// Marker trait for types that can be serialized as JSON compatible strings.
32///
33/// This trait ensures the correctness of the RPC parameters.
34///
35/// # Note
36///
37/// Please consider using the [`crate::params::ArrayParams`] and [`crate::params::ObjectParams`] than
38/// implementing this trait.
39///
40/// # Examples
41///
42/// ## Implementation for hard-coded strings
43///
44/// ```rust
45/// use jsonrpsee_core::traits::ToRpcParams;
46/// use serde_json::value::RawValue;
47///
48/// struct ManualParam;
49///
50/// impl ToRpcParams for ManualParam {
51/// fn to_rpc_params(self) -> Result<Option<Box<RawValue>>, serde_json::Error> {
52/// // Manually define a valid JSONRPC parameter.
53/// serde_json::value::to_raw_value(&[1,2,3]).map(Some)
54/// }
55/// }
56/// ```
57///
58/// ## Implementation for JSON serializable structures
59///
60/// ```rust
61/// use jsonrpsee_core::traits::ToRpcParams;
62/// use serde_json::value::RawValue;
63/// use serde::Serialize;
64///
65/// #[derive(Serialize)]
66/// struct SerParam {
67/// param_1: u8,
68/// param_2: String,
69/// };
70///
71/// impl ToRpcParams for SerParam {
72/// fn to_rpc_params(self) -> Result<Option<Box<RawValue>>, serde_json::Error> {
73/// let s = String::from_utf8(serde_json::to_vec(&self)?).expect("Valid UTF8 format");
74/// RawValue::from_string(s).map(Some)
75/// }
76/// }
77/// ```
78pub trait ToRpcParams {
79 /// Consume and serialize the type as a JSON raw value.
80 fn to_rpc_params(self) -> Result<Option<Box<RawValue>>, serde_json::Error>;
81}
82
83// To not bound the `ToRpcParams: Serialize` define a custom implementation
84// for types which are serializable.
85macro_rules! to_rpc_params_impl {
86 () => {
87 fn to_rpc_params(self) -> Result<Option<Box<RawValue>>, serde_json::Error> {
88 let json = serde_json::value::to_raw_value(&self)?;
89 Ok(Some(json))
90 }
91 };
92}
93
94impl<P: Serialize> ToRpcParams for &[P] {
95 to_rpc_params_impl!();
96}
97
98impl<P: Serialize> ToRpcParams for Vec<P> {
99 to_rpc_params_impl!();
100}
101impl<P, const N: usize> ToRpcParams for [P; N]
102where
103 [P; N]: Serialize,
104{
105 to_rpc_params_impl!();
106}
107
108macro_rules! tuple_impls {
109 ($($len:expr => ($($n:tt $name:ident)+))+) => {
110 $(
111 impl<$($name: Serialize),+> ToRpcParams for ($($name,)+) {
112 to_rpc_params_impl!();
113 }
114 )+
115 }
116}
117
118tuple_impls! {
119 1 => (0 T0)
120 2 => (0 T0 1 T1)
121 3 => (0 T0 1 T1 2 T2)
122 4 => (0 T0 1 T1 2 T2 3 T3)
123 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
124 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
125 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
126 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
127 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
128 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
129 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
130 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
131 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
132 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
133 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
134 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
135}
136
137impl ToRpcParams for Box<RawValue> {
138 fn to_rpc_params(self) -> Result<Option<Box<RawValue>>, serde_json::Error> {
139 Ok(Some(self))
140 }
141}
142
143/// Trait to generate subscription IDs.
144pub trait IdProvider: Send + Sync + std::fmt::Debug {
145 /// Returns the next ID for the subscription.
146 fn next_id(&self) -> SubscriptionId<'static>;
147}
148
149// Implement `IdProvider` for `Box<T>`
150//
151// It's not implemented for `&'_ T` because
152// of the required `'static lifetime`
153// Thus, `&dyn IdProvider` won't work.
154impl<T: IdProvider + ?Sized> IdProvider for Box<T> {
155 fn next_id(&self) -> SubscriptionId<'static> {
156 (**self).next_id()
157 }
158}
159
160/// Interface for types that can be serialized into JSON.
161pub trait ToJson {
162 /// Convert the type into a JSON value.
163 fn to_json(&self) -> Result<Box<RawValue>, serde_json::Error>;
164}
165
166/// Trait for message encryption and decryption.
167///
168/// Users can implement this trait to provide custom encryption algorithms
169/// for WebSocket message encryption.
170pub trait MessageEncryption: Send + Sync + std::fmt::Debug + 'static {
171 /// Encrypt a JSON-RPC message string.
172 fn encrypt(&self, data: &str) -> Result<String, Box<dyn std::error::Error + Send + Sync>>;
173
174 /// Decrypt a JSON-RPC message string.
175 fn decrypt(&self, data: &str) -> Result<String, Box<dyn std::error::Error + Send + Sync>>;
176}
177
178/// Policy for handling message encryption/decryption failures on the server side.
179#[derive(Debug, Clone, Copy, PartialEq, Eq)]
180pub enum MessageCryptoErrorPolicy {
181 /// Send an error response and continue processing (default).
182 SendError,
183 /// Close the connection immediately.
184 CloseConnection,
185 /// Skip the message and continue processing (only for decryption failures).
186 SkipMessage,
187}
188
189impl Default for MessageCryptoErrorPolicy {
190 fn default() -> Self {
191 Self::SendError
192 }
193}