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 #[allow(dead_code)]
38 pub fn new(a: A, b: B) -> Self {
39 SelectMuxerUpgrade(a, b)
40 }
41}
42
43impl<A, B> UpgradeInfo for SelectMuxerUpgrade<A, B>
44where
45 A: UpgradeInfo,
46 B: UpgradeInfo,
47{
48 type Info = Either<A::Info, B::Info>;
49 type InfoIter = Chain<
50 Map<<A::InfoIter as IntoIterator>::IntoIter, fn(A::Info) -> Self::Info>,
51 Map<<B::InfoIter as IntoIterator>::IntoIter, fn(B::Info) -> Self::Info>,
52 >;
53
54 fn protocol_info(&self) -> Self::InfoIter {
55 let a = self
56 .0
57 .protocol_info()
58 .into_iter()
59 .map(Either::Left as fn(A::Info) -> _);
60 let b = self
61 .1
62 .protocol_info()
63 .into_iter()
64 .map(Either::Right as fn(B::Info) -> _);
65
66 a.chain(b)
67 }
68}
69
70impl<C, A, B, TA, TB, EA, EB> InboundConnectionUpgrade<C> for SelectMuxerUpgrade<A, B>
71where
72 A: InboundConnectionUpgrade<C, Output = TA, Error = EA>,
73 B: InboundConnectionUpgrade<C, Output = TB, Error = EB>,
74{
75 type Output = future::Either<TA, TB>;
76 type Error = Either<EA, EB>;
77 type Future = EitherFuture<A::Future, B::Future>;
78
79 fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
80 match info {
81 Either::Left(info) => EitherFuture::First(self.0.upgrade_inbound(sock, info)),
82 Either::Right(info) => EitherFuture::Second(self.1.upgrade_inbound(sock, info)),
83 }
84 }
85}
86
87impl<C, A, B, TA, TB, EA, EB> OutboundConnectionUpgrade<C> for SelectMuxerUpgrade<A, B>
88where
89 A: OutboundConnectionUpgrade<C, Output = TA, Error = EA>,
90 B: OutboundConnectionUpgrade<C, Output = TB, Error = EB>,
91{
92 type Output = future::Either<TA, TB>;
93 type Error = Either<EA, EB>;
94 type Future = EitherFuture<A::Future, B::Future>;
95
96 fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
97 match info {
98 Either::Left(info) => EitherFuture::First(self.0.upgrade_outbound(sock, info)),
99 Either::Right(info) => EitherFuture::Second(self.1.upgrade_outbound(sock, info)),
100 }
101 }
102}