From bee0ea15c22460f812274e06cc4d6eb0cf2d55ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 11 Dec 2019 13:01:29 +0100 Subject: [PATCH 1/2] Implement EitherTransport --- examples/either_transport.rs | 26 +++++++++ src/lib.rs | 100 +++++++++++++++++++++++++++++++++++ 2 files changed, 126 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..7d17c300 --- /dev/null +++ b/examples/either_transport.rs @@ -0,0 +1,26 @@ +extern crate web3; + +use web3::futures::Future; + +pub type Transport = web3::EitherTransport< + web3::transports::Ipc, + web3::transports::Http, +>; + +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..b73df8d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -131,6 +131,106 @@ 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< + Item = Vec<::std::result::Result>, + Error = Error + > + 'static, + BBatch: futures::Future< + Item = Vec<::std::result::Result>, + 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< + Item = rpc::Value, + Error = Error + > + 'static, + BStream: futures::Stream< + Item = rpc::Value, + Error = Error + > + '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}; From 139da8b6ca4fc762343ae81d1d98517083c84332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Drwi=C4=99ga?= Date: Wed, 11 Dec 2019 21:30:24 +0100 Subject: [PATCH 2/2] Fix formatting. --- examples/either_transport.rs | 5 +---- src/lib.rs | 42 ++++++++++++------------------------ 2 files changed, 15 insertions(+), 32 deletions(-) diff --git a/examples/either_transport.rs b/examples/either_transport.rs index 7d17c300..6f8410e3 100644 --- a/examples/either_transport.rs +++ b/examples/either_transport.rs @@ -2,10 +2,7 @@ extern crate web3; use web3::futures::Future; -pub type Transport = web3::EitherTransport< - web3::transports::Ipc, - web3::transports::Http, ->; +pub type Transport = web3::EitherTransport; fn main() { let (_el, transport) = web3::transports::Ipc::new("./jsonrpc.ipc").unwrap(); diff --git a/src/lib.rs b/src/lib.rs index b73df8d0..5fd1891e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -145,7 +145,8 @@ pub enum EitherTransport { Right(B), } -impl Transport for EitherTransport where +impl Transport for EitherTransport +where A: Transport, B: Transport, AOut: futures::Future + 'static, @@ -168,28 +169,21 @@ impl Transport for EitherTransport where } } -impl BatchTransport for EitherTransport where +impl BatchTransport for EitherTransport +where A: BatchTransport, B: BatchTransport, A::Out: 'static, B::Out: 'static, - ABatch: futures::Future< - Item = Vec<::std::result::Result>, - Error = Error - > + 'static, - BBatch: futures::Future< - Item = Vec<::std::result::Result>, - Error = Error - > + 'static, + ABatch: futures::Future>, Error = Error> + 'static, + BBatch: futures::Future>, Error = Error> + 'static, { - type Batch = Box>, - Error = Error - >>; + type Batch = Box>, Error = Error>>; fn send_batch(&self, requests: T) -> Self::Batch where - T: IntoIterator { + T: IntoIterator, + { match *self { Self::Left(ref a) => Box::new(a.send_batch(requests)), Self::Right(ref b) => Box::new(b.send_batch(requests)), @@ -197,24 +191,16 @@ impl BatchTransport for EitherTransport where } } -impl DuplexTransport for EitherTransport where +impl DuplexTransport for EitherTransport +where A: DuplexTransport, B: DuplexTransport, A::Out: 'static, B::Out: 'static, - AStream: futures::Stream< - Item = rpc::Value, - Error = Error - > + 'static, - BStream: futures::Stream< - Item = rpc::Value, - Error = Error - > + 'static, + AStream: futures::Stream + 'static, + BStream: futures::Stream + 'static, { - type NotificationStream = Box>; + type NotificationStream = Box>; fn subscribe(&self, id: &api::SubscriptionId) -> Self::NotificationStream { match *self {