near_jsonrpc_client/methods/any/mod.rs
1//! For all intents and purposes, the predefined structures in `methods` should suffice, if you find that they
2//! don't or you crave extra flexibility, well, you can opt in to use the generic constructor `methods::any()` with the `any` feature flag.
3//!
4//! In this example, we retrieve only the parts from the genesis config response that we care about.
5//!
6//! ```toml
7//! # in Cargo.toml
8//! near-jsonrpc-client = { ..., features = ["any"] }
9//! ```
10//!
11//! ```
12//! use serde::Deserialize;
13//! use serde_json::json;
14//!
15//! # use near_jsonrpc_client::errors::JsonRpcError;
16//! use near_jsonrpc_client::{methods, JsonRpcClient};
17//! use near_primitives::serialize::u128_dec_format;
18//! use near_primitives::types::*;
19//!
20//! #[derive(Debug, Deserialize)]
21//! struct PartialGenesisConfig {
22//! protocol_version: ProtocolVersion,
23//! chain_id: String,
24//! genesis_height: BlockHeight,
25//! epoch_length: BlockHeightDelta,
26//! #[serde(with = "u128_dec_format")]
27//! min_gas_price: Balance,
28//! #[serde(with = "u128_dec_format")]
29//! max_gas_price: Balance,
30//! #[serde(with = "u128_dec_format")]
31//! total_supply: Balance,
32//! validators: Vec<AccountInfo>,
33//! }
34//!
35//! impl methods::RpcHandlerResponse for PartialGenesisConfig {}
36//!
37//! # #[tokio::main]
38//! # async fn main() -> Result<(), JsonRpcError<()>> {
39//! let client = JsonRpcClient::connect("https://rpc.mainnet.near.org");
40//!
41//! # #[cfg(feature = "any")] {
42//! let genesis_config_request = methods::any::<Result<PartialGenesisConfig, ()>>(
43//! "EXPERIMENTAL_genesis_config",
44//! json!(null),
45//! );
46//!
47//! let partial_genesis = client.call(genesis_config_request).await?;
48//!
49//! println!("{:#?}", partial_genesis);
50//! # }
51//! # Ok(())
52//! # }
53//! ```
54use super::*;
55
56use std::marker::PhantomData;
57
58pub fn request<T: AnyRequestResult>(
59 method_name: &str,
60 params: serde_json::Value,
61) -> RpcAnyRequest<T::Response, T::Error>
62where
63 T::Response: RpcHandlerResponse,
64 T::Error: RpcHandlerError,
65{
66 RpcAnyRequest {
67 method: method_name.to_string(),
68 params,
69 _data: PhantomData,
70 }
71}
72
73#[derive(Debug)]
74pub struct RpcAnyRequest<T, E> {
75 pub method: String,
76 pub params: serde_json::Value,
77 pub(crate) _data: PhantomData<(T, E)>,
78}
79
80impl<T, E> private::Sealed for RpcAnyRequest<T, E> {}
81
82impl<T, E> RpcMethod for RpcAnyRequest<T, E>
83where
84 T: RpcHandlerResponse,
85 E: RpcHandlerError,
86{
87 type Response = T;
88 type Error = E;
89
90 #[inline(always)]
91 fn method_name(&self) -> &str {
92 &self.method
93 }
94
95 fn params(&self) -> Result<serde_json::Value, io::Error> {
96 Ok(self.params.clone())
97 }
98}
99
100pub trait AnyRequestResult {
101 type Response;
102 type Error;
103}
104
105impl<T, E> AnyRequestResult for Result<T, E> {
106 type Response = T;
107 type Error = E;
108}
109
110impl<T: RpcMethod> AnyRequestResult for T {
111 type Response = T::Response;
112 type Error = T::Error;
113}