1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use std::marker::PhantomData;
use libp2p::{
core::{either::EitherOutput, transport::ListenerEvent},
futures::{future, stream, Future, FutureExt, TryFutureExt, TryStreamExt},
Multiaddr, Transport, TransportError,
};
#[derive(Debug, Clone)]
pub struct MaybeUpgrade<TInner, TUpgrade, TUpgrader> {
inner: TInner,
_marker: PhantomData<TUpgrade>,
_marker_1: PhantomData<TUpgrader>,
}
impl<TInner, TUpgrade, TUpgrader> MaybeUpgrade<TInner, TUpgrade, TUpgrader> {
pub fn new(inner: TInner) -> Self {
Self {
inner,
_marker: Default::default(),
_marker_1: Default::default(),
}
}
}
pub trait UpgradeMaybe<TInner, TUpgrade>
where
TInner: Transport,
TUpgrade: Transport,
{
type UpgradeFuture: Future<Output = Result<TUpgrade::Output, TInner::Output>> + Send;
fn try_upgrade(_other: TInner::Output) -> Self::UpgradeFuture;
}
#[allow(clippy::type_complexity)]
impl<TInner, TUpgrade, TUpgrader> Transport for MaybeUpgrade<TInner, TUpgrade, TUpgrader>
where
TInner: Transport,
TUpgrade: Transport,
TUpgrader: UpgradeMaybe<TInner, TUpgrade> + Clone,
{
type Output = EitherOutput<TInner::Output, TUpgrade::Output>;
type Error = TInner::Error;
type Listener = stream::MapOk<
TInner::Listener,
fn(
ListenerEvent<TInner::ListenerUpgrade, Self::Error>,
) -> ListenerEvent<Self::ListenerUpgrade, Self::Error>,
>;
type ListenerUpgrade = future::AndThen<
TInner::ListenerUpgrade,
future::Then<
TUpgrader::UpgradeFuture,
future::Ready<Result<Self::Output, Self::Error>>,
fn(
Result<TUpgrade::Output, TInner::Output>,
) -> future::Ready<Result<Self::Output, Self::Error>>,
>,
fn(
TInner::Output,
) -> future::Then<
TUpgrader::UpgradeFuture,
future::Ready<Result<Self::Output, Self::Error>>,
fn(
Result<TUpgrade::Output, TInner::Output>,
) -> future::Ready<Result<Self::Output, Self::Error>>,
>,
>;
type Dial = future::MapOk<TInner::Dial, fn(TInner::Output) -> Self::Output>;
fn listen_on(self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>> {
let listener: Self::Listener =
self.inner
.listen_on(addr)?
.map_ok::<_, fn(_) -> _>(|event| {
event.map(|upgrade_fut| {
upgrade_fut.and_then::<_, fn(_) -> _>(|inner| {
TUpgrader::try_upgrade(inner).then::<_, fn(_) -> _>(|res| match res {
Err(inner) => future::ok(EitherOutput::First(inner)),
Ok(upgraded) => future::ok(EitherOutput::Second(upgraded)),
})
})
})
});
Ok(listener)
}
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
let dial = self
.inner
.dial(addr)?
.map_ok::<_, fn(_) -> _>(EitherOutput::First);
Ok(dial)
}
fn address_translation(&self, listen: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
self.inner.address_translation(listen, observed)
}
}