txboost_rs/
jsonrpc.rs

1// Code adapted from: https://github.com/althea-net/guac_rs/tree/master/web3/src/jsonrpc
2// NOTE: This module only exists since there is no way to use the data structures
3// in the `ethers-providers/src/transports/common.rs` from another crate.
4use ethers::core::types::U256;
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use std::fmt;
8use thiserror::Error;
9
10/// A JSON-RPC 2.0 error
11#[derive(Serialize, Deserialize, Debug, Clone, Error)]
12pub struct JsonRpcError {
13    /// The error code
14    pub code: i64,
15    /// The error message
16    pub message: String,
17    /// Additional data
18    pub data: Option<Value>,
19}
20
21impl fmt::Display for JsonRpcError {
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        write!(
24            f,
25            "(code: {}, message: {}, data: {:?})",
26            self.code, self.message, self.data
27        )
28    }
29}
30
31fn is_zst<T>(_t: &T) -> bool {
32    std::mem::size_of::<T>() == 0
33}
34
35#[derive(Serialize, Deserialize, Debug)]
36/// A JSON-RPC request
37pub struct Request<'a, T> {
38    id: u64,
39    jsonrpc: &'a str,
40    method: &'a str,
41    #[serde(skip_serializing_if = "is_zst")]
42    params: T,
43}
44
45#[derive(Serialize, Deserialize, Debug)]
46/// A JSON-RPC Notifcation
47pub struct Notification<R> {
48    jsonrpc: String,
49    method: String,
50    pub params: Subscription<R>,
51}
52
53#[derive(Serialize, Deserialize, Debug)]
54pub struct Subscription<R> {
55    pub subscription: U256,
56    pub result: R,
57}
58
59impl<'a, T> Request<'a, T> {
60    /// Creates a new JSON RPC request
61    pub fn new(id: u64, method: &'a str, params: T) -> Self {
62        Self {
63            id,
64            jsonrpc: "2.0",
65            method,
66            params,
67        }
68    }
69}
70
71#[derive(Serialize, Deserialize, Debug, Clone)]
72pub struct Response<T> {
73    pub(crate) id: u64,
74    jsonrpc: String,
75    #[serde(flatten)]
76    pub data: ResponseData<T>,
77}
78
79#[derive(Serialize, Deserialize, Debug, Clone)]
80#[serde(untagged)]
81pub enum ResponseData<R> {
82    Error { error: JsonRpcError },
83    Success { result: Option<R> },
84}
85
86impl<R> ResponseData<R> {
87    /// Consume response and return value
88    pub fn into_result(self) -> Result<Option<R>, JsonRpcError> {
89        match self {
90            ResponseData::Success { result } => Ok(result),
91            ResponseData::Error { error } => Err(error),
92        }
93    }
94}