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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#![allow(unused_imports)]

mod bandwidth_logging;
mod behaviour;
mod build;
mod dns;
mod identity;
mod other_transport;
mod provider;
mod quic;
mod relay;
mod swarm;
mod tcp;
mod websocket;

use bandwidth_logging::*;
use behaviour::*;
use build::*;
use dns::*;
use other_transport::*;
use provider::*;
use quic::*;
use relay::*;
use swarm::*;
use tcp::*;
use websocket::*;

use super::select_security::SelectSecurityUpgrade;
use super::SwarmBuilder;

use libp2p_core::{muxing::StreamMuxerBox, upgrade::SelectUpgrade, Transport};
use libp2p_identity::Keypair;

pub trait IntoSecurityUpgrade<C> {
    type Upgrade;
    type Error;

    fn into_security_upgrade(self, keypair: &Keypair) -> Result<Self::Upgrade, Self::Error>;
}

impl<C, T, F, E> IntoSecurityUpgrade<C> for F
where
    F: for<'a> FnOnce(&'a Keypair) -> Result<T, E>,
{
    type Upgrade = T;
    type Error = E;

    fn into_security_upgrade(self, keypair: &Keypair) -> Result<Self::Upgrade, Self::Error> {
        (self)(keypair)
    }
}

impl<F1, F2, C> IntoSecurityUpgrade<C> for (F1, F2)
where
    F1: IntoSecurityUpgrade<C>,
    F2: IntoSecurityUpgrade<C>,
{
    type Upgrade = SelectSecurityUpgrade<F1::Upgrade, F2::Upgrade>;
    type Error = either::Either<F1::Error, F2::Error>;

    fn into_security_upgrade(self, keypair: &Keypair) -> Result<Self::Upgrade, Self::Error> {
        let (f1, f2) = self;

        let u1 = f1
            .into_security_upgrade(keypair)
            .map_err(either::Either::Left)?;
        let u2 = f2
            .into_security_upgrade(keypair)
            .map_err(either::Either::Right)?;

        Ok(SelectSecurityUpgrade::new(u1, u2))
    }
}

pub trait IntoMultiplexerUpgrade<C> {
    type Upgrade;

    fn into_multiplexer_upgrade(self) -> Self::Upgrade;
}

impl<C, U, F> IntoMultiplexerUpgrade<C> for F
where
    F: FnOnce() -> U,
{
    type Upgrade = U;

    fn into_multiplexer_upgrade(self) -> Self::Upgrade {
        (self)()
    }
}

impl<C, U1, U2> IntoMultiplexerUpgrade<C> for (U1, U2)
where
    U1: IntoMultiplexerUpgrade<C>,
    U2: IntoMultiplexerUpgrade<C>,
{
    type Upgrade = SelectUpgrade<U1::Upgrade, U2::Upgrade>;

    fn into_multiplexer_upgrade(self) -> Self::Upgrade {
        let (f1, f2) = self;

        let u1 = f1.into_multiplexer_upgrade();
        let u2 = f2.into_multiplexer_upgrade();

        SelectUpgrade::new(u1, u2)
    }
}

pub trait AuthenticatedMultiplexedTransport:
    Transport<
        Error = Self::E,
        Dial = Self::D,
        ListenerUpgrade = Self::U,
        Output = (libp2p_identity::PeerId, StreamMuxerBox),
    > + Send
    + Unpin
    + 'static
{
    type E: Send + Sync + 'static;
    type D: Send;
    type U: Send;
}

impl<T> AuthenticatedMultiplexedTransport for T
where
    T: Transport<Output = (libp2p_identity::PeerId, StreamMuxerBox)> + Send + Unpin + 'static,
    <T as Transport>::Error: Send + Sync + 'static,
    <T as Transport>::Dial: Send,
    <T as Transport>::ListenerUpgrade: Send,
{
    type E = T::Error;
    type D = T::Dial;
    type U = T::ListenerUpgrade;
}