libp2p_swarm/upgrade.rs
1// Copyright 2020 Parity Technologies (UK) Ltd.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21use crate::Stream;
22
23use futures::prelude::*;
24use libp2p_core::upgrade;
25
26/// Implemented automatically on all types that implement [`UpgradeInfo`](upgrade::UpgradeInfo)
27/// and `Send + 'static`.
28///
29/// Do not implement this trait yourself. Instead, please implement
30/// [`UpgradeInfo`](upgrade::UpgradeInfo).
31pub trait UpgradeInfoSend: Send + 'static {
32 /// Equivalent to [`UpgradeInfo::Info`](upgrade::UpgradeInfo::Info).
33 type Info: AsRef<str> + Clone + Send + 'static;
34 /// Equivalent to [`UpgradeInfo::InfoIter`](upgrade::UpgradeInfo::InfoIter).
35 type InfoIter: Iterator<Item = Self::Info> + Send + 'static;
36
37 /// Equivalent to [`UpgradeInfo::protocol_info`](upgrade::UpgradeInfo::protocol_info).
38 fn protocol_info(&self) -> Self::InfoIter;
39}
40
41impl<T> UpgradeInfoSend for T
42where
43 T: upgrade::UpgradeInfo + Send + 'static,
44 T::Info: Send + 'static,
45 <T::InfoIter as IntoIterator>::IntoIter: Send + 'static,
46{
47 type Info = T::Info;
48 type InfoIter = <T::InfoIter as IntoIterator>::IntoIter;
49
50 fn protocol_info(&self) -> Self::InfoIter {
51 upgrade::UpgradeInfo::protocol_info(self).into_iter()
52 }
53}
54
55/// Implemented automatically on all types that implement
56/// [`OutboundUpgrade`](upgrade::OutboundUpgrade) and `Send + 'static`.
57///
58/// Do not implement this trait yourself. Instead, please implement
59/// [`OutboundUpgrade`](upgrade::OutboundUpgrade).
60pub trait OutboundUpgradeSend: UpgradeInfoSend {
61 /// Equivalent to [`OutboundUpgrade::Output`](upgrade::OutboundUpgrade::Output).
62 type Output: Send + 'static;
63 /// Equivalent to [`OutboundUpgrade::Error`](upgrade::OutboundUpgrade::Error).
64 type Error: Send + 'static;
65 /// Equivalent to [`OutboundUpgrade::Future`](upgrade::OutboundUpgrade::Future).
66 type Future: Future<Output = Result<Self::Output, Self::Error>> + Send + 'static;
67
68 /// Equivalent to [`OutboundUpgrade::upgrade_outbound`](upgrade::OutboundUpgrade::upgrade_outbound).
69 fn upgrade_outbound(self, socket: Stream, info: Self::Info) -> Self::Future;
70}
71
72impl<T, TInfo> OutboundUpgradeSend for T
73where
74 T: upgrade::OutboundUpgrade<Stream, Info = TInfo> + UpgradeInfoSend<Info = TInfo>,
75 TInfo: AsRef<str> + Clone + Send + 'static,
76 T::Output: Send + 'static,
77 T::Error: Send + 'static,
78 T::Future: Send + 'static,
79{
80 type Output = T::Output;
81 type Error = T::Error;
82 type Future = T::Future;
83
84 fn upgrade_outbound(self, socket: Stream, info: TInfo) -> Self::Future {
85 upgrade::OutboundUpgrade::upgrade_outbound(self, socket, info)
86 }
87}
88
89/// Implemented automatically on all types that implement
90/// [`InboundUpgrade`](upgrade::InboundUpgrade) and `Send + 'static`.
91///
92/// Do not implement this trait yourself. Instead, please implement
93/// [`InboundUpgrade`](upgrade::InboundUpgrade).
94pub trait InboundUpgradeSend: UpgradeInfoSend {
95 /// Equivalent to [`InboundUpgrade::Output`](upgrade::InboundUpgrade::Output).
96 type Output: Send + 'static;
97 /// Equivalent to [`InboundUpgrade::Error`](upgrade::InboundUpgrade::Error).
98 type Error: Send + 'static;
99 /// Equivalent to [`InboundUpgrade::Future`](upgrade::InboundUpgrade::Future).
100 type Future: Future<Output = Result<Self::Output, Self::Error>> + Send + 'static;
101
102 /// Equivalent to [`InboundUpgrade::upgrade_inbound`](upgrade::InboundUpgrade::upgrade_inbound).
103 fn upgrade_inbound(self, socket: Stream, info: Self::Info) -> Self::Future;
104}
105
106impl<T, TInfo> InboundUpgradeSend for T
107where
108 T: upgrade::InboundUpgrade<Stream, Info = TInfo> + UpgradeInfoSend<Info = TInfo>,
109 TInfo: AsRef<str> + Clone + Send + 'static,
110 T::Output: Send + 'static,
111 T::Error: Send + 'static,
112 T::Future: Send + 'static,
113{
114 type Output = T::Output;
115 type Error = T::Error;
116 type Future = T::Future;
117
118 fn upgrade_inbound(self, socket: Stream, info: TInfo) -> Self::Future {
119 upgrade::InboundUpgrade::upgrade_inbound(self, socket, info)
120 }
121}
122
123/// Wraps around a type that implements [`OutboundUpgradeSend`], [`InboundUpgradeSend`], or
124/// both, and implements [`OutboundUpgrade`](upgrade::OutboundUpgrade) and/or
125/// [`InboundUpgrade`](upgrade::InboundUpgrade).
126///
127/// > **Note**: This struct is mostly an implementation detail of the library and normally
128/// > doesn't need to be used directly.
129pub struct SendWrapper<T>(pub T);
130
131impl<T: UpgradeInfoSend> upgrade::UpgradeInfo for SendWrapper<T> {
132 type Info = T::Info;
133 type InfoIter = T::InfoIter;
134
135 fn protocol_info(&self) -> Self::InfoIter {
136 UpgradeInfoSend::protocol_info(&self.0)
137 }
138}
139
140impl<T: OutboundUpgradeSend> upgrade::OutboundUpgrade<Stream> for SendWrapper<T> {
141 type Output = T::Output;
142 type Error = T::Error;
143 type Future = T::Future;
144
145 fn upgrade_outbound(self, socket: Stream, info: T::Info) -> Self::Future {
146 OutboundUpgradeSend::upgrade_outbound(self.0, socket, info)
147 }
148}
149
150impl<T: InboundUpgradeSend> upgrade::InboundUpgrade<Stream> for SendWrapper<T> {
151 type Output = T::Output;
152 type Error = T::Error;
153 type Future = T::Future;
154
155 fn upgrade_inbound(self, socket: Stream, info: T::Info) -> Self::Future {
156 InboundUpgradeSend::upgrade_inbound(self.0, socket, info)
157 }
158}