ethane/rpc/
mod.rs

1//! Functions to generate Rpcs
2//!
3//! These functions are a type-safe implementation of
4//! - the official [JSON RPC spec](https://eth.wiki/json-rpc/API)
5//! - some custom [Geth JSON namespaces](https://geth.ethereum.org/docs/rpc/server)
6//!     - [real-time events](https://geth.ethereum.org/docs/rpc/pubsub)
7//!     - [personal](https://geth.ethereum.org/docs/rpc/ns-personal)
8//!     - [txpool](https://geth.ethereum.org/docs/rpc/ns-txpool)
9//!
10//! There are some deviations between what is really supported and the official specification.
11//! This is why some functions are marked as deprecated. They will probably be removed.
12//!
13//! Use these functions to generate [Rpc](Rpc) objects and pass them to the
14//! [call](crate::Connection::call) function of a [connection](crate::Connection).
15
16use serde::de::DeserializeOwned;
17use serde::{Deserialize, Serialize};
18use serde_json::Value;
19use std::fmt::Debug;
20use std::marker::PhantomData;
21
22pub use eth::*;
23pub use net::*;
24pub use personal::*;
25pub use sub::*;
26//pub(crate) use sub::eth_unsubscribe;
27pub use txpool::*;
28pub use web3::*;
29
30mod eth;
31mod net;
32mod personal;
33mod sub;
34mod txpool;
35mod web3;
36
37/// Wrapper for the remote procedure call
38///
39/// This is usually not directly needed and returned by the [functions](crate::rpc) which
40/// wrap the different namespaces. However, it is also possible to create custom Rpc structs.
41#[repr(C)]
42#[derive(Serialize, Debug)]
43pub struct Rpc<T: DeserializeOwned + Debug> {
44    #[serde(rename = "jsonrpc")]
45    /// The version of the JSON RPC spec
46    pub json_rpc: &'static str,
47    /// The method which is called
48    pub method: String,
49    /// Arguments supplied to the method. Can be an empty Vec.
50    pub params: Vec<Value>,
51    /// The id for the request
52    pub id: usize,
53    /// Type annotation needed for the result
54    #[serde(skip_serializing)]
55    pub result_type: PhantomData<T>,
56}
57
58#[derive(Deserialize)]
59pub struct RpcResponse<'a, T: 'a> {
60    pub id: usize,
61    pub jsonrpc: &'a str,
62    pub result: T,
63}
64
65impl<T: DeserializeOwned + Debug> Rpc<T> {
66    const JSON_RPC: &'static str = "2.0";
67
68    pub(crate) fn new(method: &str) -> Rpc<T> {
69        Rpc {
70            json_rpc: Self::JSON_RPC,
71            method: String::from(method),
72            params: Vec::new(),
73            id: Default::default(),
74            result_type: PhantomData,
75        }
76    }
77
78    pub(crate) fn add_param<U: Serialize + Debug>(&mut self, parameter: U) {
79        if let Ok(serialized_param) = serde_json::to_value(&parameter) {
80            self.params.push(serialized_param);
81        }
82    }
83}