libp2p/builder/
select_muxer.rs1#![allow(unreachable_pub)]
22
23use std::iter::{Chain, Map};
24
25use either::Either;
26use futures::future;
27use libp2p_core::{
28 either::EitherFuture,
29 upgrade::{InboundConnectionUpgrade, OutboundConnectionUpgrade},
30 UpgradeInfo,
31};
32
33#[derive(Debug, Clone)]
34pub struct SelectMuxerUpgrade<A, B>(A, B);
35
36impl<A, B> SelectMuxerUpgrade<A, B> {
37 pub fn new(a: A, b: B) -> Self {
38 SelectMuxerUpgrade(a, b)
39 }
40}
41
42impl<A, B> UpgradeInfo for SelectMuxerUpgrade<A, B>
43where
44 A: UpgradeInfo,
45 B: UpgradeInfo,
46{
47 type Info = Either<A::Info, B::Info>;
48 type InfoIter = Chain<
49 Map<<A::InfoIter as IntoIterator>::IntoIter, fn(A::Info) -> Self::Info>,
50 Map<<B::InfoIter as IntoIterator>::IntoIter, fn(B::Info) -> Self::Info>,
51 >;
52
53 fn protocol_info(&self) -> Self::InfoIter {
54 let a = self
55 .0
56 .protocol_info()
57 .into_iter()
58 .map(Either::Left as fn(A::Info) -> _);
59 let b = self
60 .1
61 .protocol_info()
62 .into_iter()
63 .map(Either::Right as fn(B::Info) -> _);
64
65 a.chain(b)
66 }
67}
68
69impl<C, A, B, TA, TB, EA, EB> InboundConnectionUpgrade<C> for SelectMuxerUpgrade<A, B>
70where
71 A: InboundConnectionUpgrade<C, Output = TA, Error = EA>,
72 B: InboundConnectionUpgrade<C, Output = TB, Error = EB>,
73{
74 type Output = future::Either<TA, TB>;
75 type Error = Either<EA, EB>;
76 type Future = EitherFuture<A::Future, B::Future>;
77
78 fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
79 match info {
80 Either::Left(info) => EitherFuture::First(self.0.upgrade_inbound(sock, info)),
81 Either::Right(info) => EitherFuture::Second(self.1.upgrade_inbound(sock, info)),
82 }
83 }
84}
85
86impl<C, A, B, TA, TB, EA, EB> OutboundConnectionUpgrade<C> for SelectMuxerUpgrade<A, B>
87where
88 A: OutboundConnectionUpgrade<C, Output = TA, Error = EA>,
89 B: OutboundConnectionUpgrade<C, Output = TB, Error = EB>,
90{
91 type Output = future::Either<TA, TB>;
92 type Error = Either<EA, EB>;
93 type Future = EitherFuture<A::Future, B::Future>;
94
95 fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
96 match info {
97 Either::Left(info) => EitherFuture::First(self.0.upgrade_outbound(sock, info)),
98 Either::Right(info) => EitherFuture::Second(self.1.upgrade_outbound(sock, info)),
99 }
100 }
101}