libp2p_core/upgrade/
select.rs1use crate::either::EitherFuture;
22use crate::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo};
23use either::Either;
24use futures::future;
25use std::iter::{Chain, Map};
26
27#[derive(Debug, Clone)]
32pub struct SelectUpgrade<A, B>(A, B);
33
34impl<A, B> SelectUpgrade<A, B> {
35 pub fn new(a: A, b: B) -> Self {
39 SelectUpgrade(a, b)
40 }
41}
42
43impl<A, B> UpgradeInfo for SelectUpgrade<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> InboundUpgrade<C> for SelectUpgrade<A, B>
71where
72 A: InboundUpgrade<C, Output = TA, Error = EA>,
73 B: InboundUpgrade<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> OutboundUpgrade<C> for SelectUpgrade<A, B>
88where
89 A: OutboundUpgrade<C, Output = TA, Error = EA>,
90 B: OutboundUpgrade<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}