pub mod account;
pub mod chain;
pub mod info;
pub mod state;
use std::str;
use futures::{future::BoxFuture, TryFutureExt};
use http::Response;
use hyper::Body;
use serde::{Deserialize, Serialize};
use warp::{
filters::BoxedFilter,
reject::{self, Reject},
Filter,
};
use warp_json_rpc::{filters, Builder};
use super::{ApiRequest, ReactorEventT};
use crate::effect::EffectBuilder;
pub const RPC_API_PATH: &str = "rpc";
#[repr(i64)]
enum ErrorCode {
NoSuchDeploy = 32000,
NoSuchBlock = 32001,
ParseQueryKey = 32002,
QueryFailed = 32003,
QueryFailedToExecute = 32004,
ParseGetBalanceURef = 32005,
GetBalanceFailed = 32006,
GetBalanceFailedToExecute = 32007,
}
#[derive(Debug)]
pub(super) struct Error(String);
impl Reject for Error {}
impl From<anyhow::Error> for Error {
fn from(error: anyhow::Error) -> Self {
Error(error.to_string())
}
}
pub trait RpcWithParams {
const METHOD: &'static str;
type RequestParams: Serialize + for<'de> Deserialize<'de> + Send + 'static;
type ResponseResult: Serialize + for<'de> Deserialize<'de> + Send + 'static;
}
pub(super) trait RpcWithParamsExt: RpcWithParams {
fn create_filter<REv: ReactorEventT>(
effect_builder: EffectBuilder<REv>,
) -> BoxedFilter<(Response<Body>,)> {
warp::path(RPC_API_PATH)
.and(filters::json_rpc())
.and(filters::method(Self::METHOD))
.and(filters::params::<Self::RequestParams>())
.and_then(
move |response_builder: Builder, params: Self::RequestParams| {
Self::handle_request(effect_builder, response_builder, params)
.map_err(reject::custom)
},
)
.boxed()
}
fn handle_request<REv: ReactorEventT>(
effect_builder: EffectBuilder<REv>,
response_builder: Builder,
params: Self::RequestParams,
) -> BoxFuture<'static, Result<Response<Body>, Error>>;
}
pub trait RpcWithoutParams {
const METHOD: &'static str;
type ResponseResult: Serialize + for<'de> Deserialize<'de> + Send + 'static;
}
pub(super) trait RpcWithoutParamsExt: RpcWithoutParams {
fn create_filter<REv: ReactorEventT>(
effect_builder: EffectBuilder<REv>,
) -> BoxedFilter<(Response<Body>,)> {
warp::path(RPC_API_PATH)
.and(filters::json_rpc())
.and(filters::method(Self::METHOD))
.and_then(move |response_builder: Builder| {
Self::handle_request(effect_builder, response_builder).map_err(reject::custom)
})
.boxed()
}
fn handle_request<REv: ReactorEventT>(
effect_builder: EffectBuilder<REv>,
response_builder: Builder,
) -> BoxFuture<'static, Result<Response<Body>, Error>>;
}
pub trait RpcWithOptionalParams {
const METHOD: &'static str;
type OptionalRequestParams: Serialize + for<'de> Deserialize<'de> + Send + 'static;
type ResponseResult: Serialize + for<'de> Deserialize<'de> + Send + 'static;
}
pub(super) trait RpcWithOptionalParamsExt: RpcWithOptionalParams {
fn create_filter<REv: ReactorEventT>(
effect_builder: EffectBuilder<REv>,
) -> BoxedFilter<(Response<Body>,)> {
let with_params = warp::path(RPC_API_PATH)
.and(filters::json_rpc())
.and(filters::method(Self::METHOD))
.and(filters::params::<Self::OptionalRequestParams>())
.and_then(
move |response_builder: Builder, params: Self::OptionalRequestParams| {
Self::handle_request(effect_builder, response_builder, Some(params))
.map_err(reject::custom)
},
);
let without_params = warp::path(RPC_API_PATH)
.and(filters::json_rpc())
.and(filters::method(Self::METHOD))
.and_then(move |response_builder: Builder| {
Self::handle_request(effect_builder, response_builder, None).map_err(reject::custom)
});
with_params.or(without_params).unify().boxed()
}
fn handle_request<REv: ReactorEventT>(
effect_builder: EffectBuilder<REv>,
response_builder: Builder,
maybe_params: Option<Self::OptionalRequestParams>,
) -> BoxFuture<'static, Result<Response<Body>, Error>>;
}