1use crate::either::EitherFuture;
22use crate::upgrade::{
23 InboundConnectionUpgrade, InboundUpgrade, OutboundConnectionUpgrade, OutboundUpgrade,
24 UpgradeInfo,
25};
26use either::Either;
27use futures::future;
28use std::iter::{Chain, Map};
29
30#[derive(Debug, Clone)]
35pub struct SelectUpgrade<A, B>(A, B);
36
37impl<A, B> SelectUpgrade<A, B> {
38 pub fn new(a: A, b: B) -> Self {
42 SelectUpgrade(a, b)
43 }
44}
45
46impl<A, B> UpgradeInfo for SelectUpgrade<A, B>
47where
48 A: UpgradeInfo,
49 B: UpgradeInfo,
50{
51 type Info = Either<A::Info, B::Info>;
52 type InfoIter = Chain<
53 Map<<A::InfoIter as IntoIterator>::IntoIter, fn(A::Info) -> Self::Info>,
54 Map<<B::InfoIter as IntoIterator>::IntoIter, fn(B::Info) -> Self::Info>,
55 >;
56
57 fn protocol_info(&self) -> Self::InfoIter {
58 let a = self
59 .0
60 .protocol_info()
61 .into_iter()
62 .map(Either::Left as fn(A::Info) -> _);
63 let b = self
64 .1
65 .protocol_info()
66 .into_iter()
67 .map(Either::Right as fn(B::Info) -> _);
68
69 a.chain(b)
70 }
71}
72
73impl<C, A, B, TA, TB, EA, EB> InboundUpgrade<C> for SelectUpgrade<A, B>
74where
75 A: InboundUpgrade<C, Output = TA, Error = EA>,
76 B: InboundUpgrade<C, Output = TB, Error = EB>,
77{
78 type Output = future::Either<TA, TB>;
79 type Error = Either<EA, EB>;
80 type Future = EitherFuture<A::Future, B::Future>;
81
82 fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
83 match info {
84 Either::Left(info) => EitherFuture::First(self.0.upgrade_inbound(sock, info)),
85 Either::Right(info) => EitherFuture::Second(self.1.upgrade_inbound(sock, info)),
86 }
87 }
88}
89
90impl<C, A, B, TA, TB, EA, EB> InboundConnectionUpgrade<C> for SelectUpgrade<A, B>
91where
92 A: InboundConnectionUpgrade<C, Output = TA, Error = EA>,
93 B: InboundConnectionUpgrade<C, Output = TB, Error = EB>,
94{
95 type Output = future::Either<TA, TB>;
96 type Error = Either<EA, EB>;
97 type Future = EitherFuture<A::Future, B::Future>;
98
99 fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
100 match info {
101 Either::Left(info) => EitherFuture::First(self.0.upgrade_inbound(sock, info)),
102 Either::Right(info) => EitherFuture::Second(self.1.upgrade_inbound(sock, info)),
103 }
104 }
105}
106
107impl<C, A, B, TA, TB, EA, EB> OutboundUpgrade<C> for SelectUpgrade<A, B>
108where
109 A: OutboundUpgrade<C, Output = TA, Error = EA>,
110 B: OutboundUpgrade<C, Output = TB, Error = EB>,
111{
112 type Output = future::Either<TA, TB>;
113 type Error = Either<EA, EB>;
114 type Future = EitherFuture<A::Future, B::Future>;
115
116 fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
117 match info {
118 Either::Left(info) => EitherFuture::First(self.0.upgrade_outbound(sock, info)),
119 Either::Right(info) => EitherFuture::Second(self.1.upgrade_outbound(sock, info)),
120 }
121 }
122}
123
124impl<C, A, B, TA, TB, EA, EB> OutboundConnectionUpgrade<C> for SelectUpgrade<A, B>
125where
126 A: OutboundConnectionUpgrade<C, Output = TA, Error = EA>,
127 B: OutboundConnectionUpgrade<C, Output = TB, Error = EB>,
128{
129 type Output = future::Either<TA, TB>;
130 type Error = Either<EA, EB>;
131 type Future = EitherFuture<A::Future, B::Future>;
132
133 fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
134 match info {
135 Either::Left(info) => EitherFuture::First(self.0.upgrade_outbound(sock, info)),
136 Either::Right(info) => EitherFuture::Second(self.1.upgrade_outbound(sock, info)),
137 }
138 }
139}