ic_web3_rs/transports/
either.rs1use crate::{api, error, rpc, BatchTransport, DuplexTransport, RequestId, Transport};
4use futures::{
5 future::{BoxFuture, FutureExt},
6 stream::{BoxStream, StreamExt},
7};
8use ic_cdk::api::management_canister::http_request::TransformContext;
9
10use super::ic_http_client::CallOptions;
11
12#[derive(Debug, Clone)]
19pub enum Either<A, B> {
20 Left(A),
22 Right(B),
24}
25
26impl<A, B, AOut, BOut> Transport for Either<A, B>
27where
28 A: Transport<Out = AOut>,
29 B: Transport<Out = BOut>,
30 AOut: futures::Future<Output = error::Result<rpc::Value>> + 'static + Send,
31 BOut: futures::Future<Output = error::Result<rpc::Value>> + 'static + Send,
32{
33 type Out = BoxFuture<'static, error::Result<rpc::Value>>;
34
35 fn prepare(&self, method: &str, params: Vec<rpc::Value>) -> (RequestId, rpc::Call) {
36 match *self {
37 Self::Left(ref a) => a.prepare(method, params),
38 Self::Right(ref b) => b.prepare(method, params),
39 }
40 }
41
42 fn send(&self, id: RequestId, request: rpc::Call, options: CallOptions) -> Self::Out {
43 match *self {
44 Self::Left(ref a) => a.send(id, request, options).boxed(),
45 Self::Right(ref b) => b.send(id, request, options).boxed(),
46 }
47 }
48
49 fn set_max_response_bytes(&mut self, v: u64) {
50 match *self {
51 Self::Left(ref mut a) => a.set_max_response_bytes(v),
52 Self::Right(ref mut b) => b.set_max_response_bytes(v),
53 }
54 }
55}
56
57impl<A, B, ABatch, BBatch> BatchTransport for Either<A, B>
58where
59 A: BatchTransport<Batch = ABatch>,
60 B: BatchTransport<Batch = BBatch>,
61 A::Out: 'static + Send,
62 B::Out: 'static + Send,
63 ABatch: futures::Future<Output = error::Result<Vec<error::Result<rpc::Value>>>> + 'static + Send,
64 BBatch: futures::Future<Output = error::Result<Vec<error::Result<rpc::Value>>>> + 'static + Send,
65{
66 type Batch = BoxFuture<'static, error::Result<Vec<error::Result<rpc::Value>>>>;
67
68 fn send_batch<T>(&self, requests: T) -> Self::Batch
69 where
70 T: IntoIterator<Item = (RequestId, rpc::Call)>,
71 {
72 match *self {
73 Self::Left(ref a) => a.send_batch(requests).boxed(),
74 Self::Right(ref b) => b.send_batch(requests).boxed(),
75 }
76 }
77}
78
79impl<A, B, AStream, BStream> DuplexTransport for Either<A, B>
80where
81 A: DuplexTransport<NotificationStream = AStream>,
82 B: DuplexTransport<NotificationStream = BStream>,
83 A::Out: 'static + Send,
84 B::Out: 'static + Send,
85 AStream: futures::Stream<Item = rpc::Value> + 'static + Send,
86 BStream: futures::Stream<Item = rpc::Value> + 'static + Send,
87{
88 type NotificationStream = BoxStream<'static, rpc::Value>;
89
90 fn subscribe(&self, id: api::SubscriptionId) -> error::Result<Self::NotificationStream> {
91 Ok(match *self {
92 Self::Left(ref a) => a.subscribe(id)?.boxed(),
93 Self::Right(ref b) => b.subscribe(id)?.boxed(),
94 })
95 }
96
97 fn unsubscribe(&self, id: api::SubscriptionId) -> error::Result {
98 match *self {
99 Self::Left(ref a) => a.unsubscribe(id),
100 Self::Right(ref b) => b.unsubscribe(id),
101 }
102 }
103}