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}