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
use serde::{Deserialize, Serialize};
pub use serde_json::Error as JsonError;

/// A JSON-RPC error object.
#[derive(Clone, Debug, PartialEq, Deserialize)]
pub struct RpcError {
    /// The integer identifier of the error.
    pub code: i32,
    /// A string describing the error.
    pub message: String,
    /// Additional data specific to the error
    pub data: Option<serde_json::Value>,
}

/// Represents the JSON-RPC request object.
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct Request {
    pub method: String,
    pub params: serde_json::Value,
    pub id: serde_json::Value,
    pub jsonrpc: String,
}

impl Request {
    pub fn build() -> RequestBuilder {
        RequestBuilder::default()
    }
}

#[derive(Default)]
pub struct RequestBuilder {
    id: Option<serde_json::Value>,
    method: Option<String>,
    params: Option<serde_json::Value>,
    json_rpc: Option<String>,
}

#[derive(Debug)]
pub struct IncompleteRequest;

impl RequestBuilder {
    pub fn method<S: Into<String>>(mut self, method: S) -> Self {
        self.method = Some(method.into());
        self
    }

    pub fn id<I: Into<serde_json::Value>>(mut self, id: I) -> Self {
        self.id = Some(id.into());
        self
    }

    pub fn params<V: Into<serde_json::Value>>(mut self, params: V) -> Self {
        self.params = Some(params.into());
        self
    }

    pub fn jsonrpc<S: Into<String>>(mut self, json_rpc: S) -> Self {
        self.json_rpc = Some(json_rpc.into());
        self
    }

    pub fn finish(self) -> Result<Request, IncompleteRequest> {
        let jsonrpc = if let Some(jsonrpc) = self.json_rpc {
            jsonrpc
        } else {
            "2.0".to_string()
        };
        if let (Some(id), Some(method)) = (self.id, self.method) {
            if let Some(params) = self.params {
                Ok(Request {
                    id,
                    method,
                    params,
                    jsonrpc,
                })
            } else {
                Ok(Request {
                    id,
                    method,
                    params: serde_json::Value::Null,
                    jsonrpc,
                })
            }
        } else {
            Err(IncompleteRequest)
        }
    }
}

/// Represents the JSON-RPC response object.
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct Response {
    pub result: Option<serde_json::Value>,
    pub error: Option<RpcError>,
    pub id: serde_json::Value,
    pub jsonrpc: Option<String>,
}

impl Response {
    /// Extract the result.
    pub fn result<T: serde::de::DeserializeOwned>(&self) -> Option<Result<T, JsonError>> {
        self.result.as_ref().map(T::deserialize)
    }

    /// Extract the result, consuming the response.
    pub fn into_result<T: serde::de::DeserializeOwned>(self) -> Option<Result<T, JsonError>> {
        self.result.map(serde_json::from_value)
    }

    /// Returns the [`RpcError`].
    pub fn error(self) -> Option<RpcError> {
        self.error
    }

    /// Returns `true` if the result field is [`Some`] value.
    pub fn is_result(&self) -> bool {
        self.result.is_some()
    }

    /// Returns `true` if the error field is [`Some`] value.
    pub fn is_error(&self) -> bool {
        self.error.is_some()
    }
}