From 897fcfdbb0d53ca84b81bfdb21e8c8634d04e0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 11 Dec 2019 22:24:25 +0100 Subject: [PATCH] Implement EitherTransport (#297) * Implement EitherTransport * Fix formatting. --- examples/either_transport.rs | 23 ++++++++++ src/lib.rs | 86 ++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 examples/either_transport.rs diff --git a/examples/either_transport.rs b/examples/either_transport.rs new file mode 100644 index 00000000..6f8410e3 --- /dev/null +++ b/examples/either_transport.rs @@ -0,0 +1,23 @@ +extern crate web3; + +use web3::futures::Future; + +pub type Transport = web3::EitherTransport; + +fn main() { + let (_el, transport) = web3::transports::Ipc::new("./jsonrpc.ipc").unwrap(); + + run(web3::EitherTransport::Left(transport)); +} + +fn run(transport: Transport) { + let web3 = web3::Web3::new(transport); + + println!("Calling accounts."); + let accounts = web3.eth().accounts().wait().unwrap(); + println!("Accounts: {:?}", accounts); + + println!("Calling balance."); + let balance = web3.eth().balance("0x0".parse().unwrap(), None).wait().unwrap(); + println!("Balance: {}", balance); +} diff --git a/src/lib.rs b/src/lib.rs index 5938fb4b..5fd1891e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -131,6 +131,92 @@ where } } +/// A wrapper over two possible transports. +/// +/// This type can be used to write semi-generic +/// code without the hassle of making all functions generic. +/// +/// See the `examples` folder for an example how to use it. +#[derive(Debug, Clone)] +pub enum EitherTransport { + /// First possible transport. + Left(A), + /// Second possible transport. + Right(B), +} + +impl Transport for EitherTransport +where + A: Transport, + B: Transport, + AOut: futures::Future + 'static, + BOut: futures::Future + 'static, +{ + type Out = Box>; + + fn prepare(&self, method: &str, params: Vec) -> (RequestId, rpc::Call) { + match *self { + Self::Left(ref a) => a.prepare(method, params), + Self::Right(ref b) => b.prepare(method, params), + } + } + + fn send(&self, id: RequestId, request: rpc::Call) -> Self::Out { + match *self { + Self::Left(ref a) => Box::new(a.send(id, request)), + Self::Right(ref b) => Box::new(b.send(id, request)), + } + } +} + +impl BatchTransport for EitherTransport +where + A: BatchTransport, + B: BatchTransport, + A::Out: 'static, + B::Out: 'static, + ABatch: futures::Future>, Error = Error> + 'static, + BBatch: futures::Future>, Error = Error> + 'static, +{ + type Batch = Box>, Error = Error>>; + + fn send_batch(&self, requests: T) -> Self::Batch + where + T: IntoIterator, + { + match *self { + Self::Left(ref a) => Box::new(a.send_batch(requests)), + Self::Right(ref b) => Box::new(b.send_batch(requests)), + } + } +} + +impl DuplexTransport for EitherTransport +where + A: DuplexTransport, + B: DuplexTransport, + A::Out: 'static, + B::Out: 'static, + AStream: futures::Stream + 'static, + BStream: futures::Stream + 'static, +{ + type NotificationStream = Box>; + + fn subscribe(&self, id: &api::SubscriptionId) -> Self::NotificationStream { + match *self { + Self::Left(ref a) => Box::new(a.subscribe(id)), + Self::Right(ref b) => Box::new(b.subscribe(id)), + } + } + + fn unsubscribe(&self, id: &api::SubscriptionId) { + match *self { + Self::Left(ref a) => a.unsubscribe(id), + Self::Right(ref b) => b.unsubscribe(id), + } + } +} + #[cfg(test)] mod tests { use super::{rpc, Error, RequestId, Transport};