#![allow(
clippy::type_complexity,
clippy::wrong_self_convention,
clippy::single_match,
clippy::let_unit_value,
clippy::match_wild_err_arm
)]
#![warn(missing_docs)]
use jsonrpc_core as rpc;
#[macro_use]
pub extern crate futures;
#[macro_use]
pub mod helpers;
pub mod api;
pub mod contract;
pub mod error;
pub mod transports;
pub mod types;
pub mod confirm;
pub use crate::api::Web3;
pub use crate::error::Error;
pub type Result<T> = Box<dyn futures::Future<Item = T, Error = Error> + Send + 'static>;
pub type RequestId = usize;
pub trait Transport: ::std::fmt::Debug + Clone {
type Out: futures::Future<Item = rpc::Value, Error = Error>;
fn prepare(&self, method: &str, params: Vec<rpc::Value>) -> (RequestId, rpc::Call);
fn send(&self, id: RequestId, request: rpc::Call) -> Self::Out;
fn execute(&self, method: &str, params: Vec<rpc::Value>) -> Self::Out {
let (id, request) = self.prepare(method, params);
self.send(id, request)
}
}
pub trait BatchTransport: Transport {
type Batch: futures::Future<Item = Vec<::std::result::Result<rpc::Value, Error>>, Error = Error>;
fn send_batch<T>(&self, requests: T) -> Self::Batch
where
T: IntoIterator<Item = (RequestId, rpc::Call)>;
}
pub trait DuplexTransport: Transport {
type NotificationStream: futures::Stream<Item = rpc::Value, Error = Error>;
fn subscribe(&self, id: &api::SubscriptionId) -> Self::NotificationStream;
fn unsubscribe(&self, id: &api::SubscriptionId);
}
impl<X, T> Transport for X
where
T: Transport + ?Sized,
X: ::std::ops::Deref<Target = T>,
X: ::std::fmt::Debug,
X: Clone,
{
type Out = T::Out;
fn prepare(&self, method: &str, params: Vec<rpc::Value>) -> (RequestId, rpc::Call) {
(**self).prepare(method, params)
}
fn send(&self, id: RequestId, request: rpc::Call) -> Self::Out {
(**self).send(id, request)
}
}
impl<X, T> BatchTransport for X
where
T: BatchTransport + ?Sized,
X: ::std::ops::Deref<Target = T>,
X: ::std::fmt::Debug,
X: Clone,
{
type Batch = T::Batch;
fn send_batch<I>(&self, requests: I) -> Self::Batch
where
I: IntoIterator<Item = (RequestId, rpc::Call)>,
{
(**self).send_batch(requests)
}
}
impl<X, T> DuplexTransport for X
where
T: DuplexTransport + ?Sized,
X: ::std::ops::Deref<Target = T>,
X: ::std::fmt::Debug,
X: Clone,
{
type NotificationStream = T::NotificationStream;
fn subscribe(&self, id: &api::SubscriptionId) -> Self::NotificationStream {
(**self).subscribe(id)
}
fn unsubscribe(&self, id: &api::SubscriptionId) {
(**self).unsubscribe(id)
}
}
#[cfg(test)]
mod tests {
use super::{rpc, Error, RequestId, Transport};
use crate::api::Web3;
use futures::Future;
use std::sync::Arc;
#[derive(Debug, Clone)]
struct FakeTransport;
impl Transport for FakeTransport {
type Out = Box<dyn Future<Item = rpc::Value, Error = Error> + Send + 'static>;
fn prepare(&self, _method: &str, _params: Vec<rpc::Value>) -> (RequestId, rpc::Call) {
unimplemented!()
}
fn send(&self, _id: RequestId, _request: rpc::Call) -> Self::Out {
unimplemented!()
}
}
#[test]
fn should_allow_to_use_arc_as_transport() {
let transport = Arc::new(FakeTransport);
let transport2 = transport.clone();
let _web3_1 = Web3::new(transport);
let _web3_2 = Web3::new(transport2);
}
}