casper_json_rpc/
response.rs

1use std::borrow::Cow;
2
3use serde::{
4    de::{DeserializeOwned, Deserializer},
5    Deserialize, Serialize,
6};
7use serde_json::Value;
8use tracing::error;
9
10use super::{Error, JSON_RPC_VERSION};
11
12/// A JSON-RPC response.
13#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
14#[serde(deny_unknown_fields, untagged)]
15pub enum Response {
16    /// A successful RPC execution.
17    Success {
18        /// The JSON-RPC version field.
19        #[serde(deserialize_with = "set_jsonrpc_field")]
20        jsonrpc: Cow<'static, str>,
21        /// The same ID as was passed in the corresponding request.
22        id: Value,
23        /// The successful result of executing the RPC.
24        result: Value,
25    },
26    /// An RPC execution which failed.
27    Failure {
28        /// The JSON-RPC version field.
29        #[serde(deserialize_with = "set_jsonrpc_field")]
30        jsonrpc: Cow<'static, str>,
31        /// The same ID as was passed in the corresponding request.
32        id: Value,
33        /// The error encountered while executing the RPC.
34        error: Error,
35    },
36}
37
38impl Response {
39    /// Returns a new `Response::Success`.
40    pub fn new_success(id: Value, result: Value) -> Self {
41        Response::Success {
42            jsonrpc: Cow::Borrowed(JSON_RPC_VERSION),
43            id,
44            result,
45        }
46    }
47
48    /// Returns a new `Response::Failure`.
49    pub fn new_failure(id: Value, error: Error) -> Self {
50        Response::Failure {
51            jsonrpc: Cow::Borrowed(JSON_RPC_VERSION),
52            id,
53            error,
54        }
55    }
56
57    /// Returns `true` is this is a `Response::Success`.
58    pub fn is_success(&self) -> bool {
59        matches!(self, Response::Success { .. })
60    }
61
62    /// Returns `true` is this is a `Response::Failure`.
63    pub fn is_failure(&self) -> bool {
64        matches!(self, Response::Failure { .. })
65    }
66
67    /// Returns the "result" field, or `None` if this is a `Response::Failure`.
68    pub fn raw_result(&self) -> Option<&Value> {
69        match &self {
70            Response::Success { result, .. } => Some(result),
71            Response::Failure { .. } => None,
72        }
73    }
74
75    /// Returns the "result" field parsed as `T`, or `None` if this is a `Response::Failure` or if
76    /// parsing fails.
77    pub fn result<T: DeserializeOwned>(&self) -> Option<T> {
78        match &self {
79            Response::Success { result, .. } => serde_json::from_value(result.clone())
80                .map_err(|error| {
81                    error!("failed to parse: {}", error);
82                })
83                .ok(),
84            Response::Failure { .. } => None,
85        }
86    }
87
88    /// Returns the "error" field or `None` if this is a `Response::Success`.
89    pub fn error(&self) -> Option<&Error> {
90        match &self {
91            Response::Success { .. } => None,
92            Response::Failure { error, .. } => Some(error),
93        }
94    }
95
96    /// Returns the "id" field.
97    pub fn id(&self) -> &Value {
98        match &self {
99            Response::Success { id, .. } | Response::Failure { id, .. } => id,
100        }
101    }
102}
103
104fn set_jsonrpc_field<'de, D: Deserializer<'de>>(
105    _deserializer: D,
106) -> Result<Cow<'static, str>, D::Error> {
107    Ok(Cow::Borrowed(JSON_RPC_VERSION))
108}