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 futures::prelude::*;
22use libp2p_core::upgrade;
23
24use crate::Stream;
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
69 /// [`OutboundUpgrade::upgrade_outbound`](upgrade::OutboundUpgrade::upgrade_outbound).
70 fn upgrade_outbound(self, socket: Stream, info: Self::Info) -> Self::Future;
71}
72
73impl<T, TInfo> OutboundUpgradeSend for T
74where
75 T: upgrade::OutboundUpgrade<Stream, Info = TInfo> + UpgradeInfoSend<Info = TInfo>,
76 TInfo: AsRef<str> + Clone + Send + 'static,
77 T::Output: Send + 'static,
78 T::Error: Send + 'static,
79 T::Future: Send + 'static,
80{
81 type Output = T::Output;
82 type Error = T::Error;
83 type Future = T::Future;
84
85 fn upgrade_outbound(self, socket: Stream, info: TInfo) -> Self::Future {
86 upgrade::OutboundUpgrade::upgrade_outbound(self, socket, info)
87 }
88}
89
90/// Implemented automatically on all types that implement
91/// [`InboundUpgrade`](upgrade::InboundUpgrade) and `Send + 'static`.
92///
93/// Do not implement this trait yourself. Instead, please implement
94/// [`InboundUpgrade`](upgrade::InboundUpgrade).
95pub trait InboundUpgradeSend: UpgradeInfoSend {
96 /// Equivalent to [`InboundUpgrade::Output`](upgrade::InboundUpgrade::Output).
97 type Output: Send + 'static;
98 /// Equivalent to [`InboundUpgrade::Error`](upgrade::InboundUpgrade::Error).
99 type Error: Send + 'static;
100 /// Equivalent to [`InboundUpgrade::Future`](upgrade::InboundUpgrade::Future).
101 type Future: Future<Output = Result<Self::Output, Self::Error>> + Send + 'static;
102
103 /// Equivalent to [`InboundUpgrade::upgrade_inbound`](upgrade::InboundUpgrade::upgrade_inbound).
104 fn upgrade_inbound(self, socket: Stream, info: Self::Info) -> Self::Future;
105}
106
107impl<T, TInfo> InboundUpgradeSend for T
108where
109 T: upgrade::InboundUpgrade<Stream, Info = TInfo> + UpgradeInfoSend<Info = TInfo>,
110 TInfo: AsRef<str> + Clone + Send + 'static,
111 T::Output: Send + 'static,
112 T::Error: Send + 'static,
113 T::Future: Send + 'static,
114{
115 type Output = T::Output;
116 type Error = T::Error;
117 type Future = T::Future;
118
119 fn upgrade_inbound(self, socket: Stream, info: TInfo) -> Self::Future {
120 upgrade::InboundUpgrade::upgrade_inbound(self, socket, info)
121 }
122}
123
124/// Wraps around a type that implements [`OutboundUpgradeSend`], [`InboundUpgradeSend`], or
125///
126/// both, and implements [`OutboundUpgrade`](upgrade::OutboundUpgrade) and/or
127/// [`InboundUpgrade`](upgrade::InboundUpgrade).
128///
129/// > **Note**: This struct is mostly an implementation detail of the library and normally
130/// > doesn't need to be used directly.
131pub struct SendWrapper<T>(pub T);
132
133impl<T: UpgradeInfoSend> upgrade::UpgradeInfo for SendWrapper<T> {
134 type Info = T::Info;
135 type InfoIter = T::InfoIter;
136
137 fn protocol_info(&self) -> Self::InfoIter {
138 UpgradeInfoSend::protocol_info(&self.0)
139 }
140}
141
142impl<T: OutboundUpgradeSend> upgrade::OutboundUpgrade<Stream> for SendWrapper<T> {
143 type Output = T::Output;
144 type Error = T::Error;
145 type Future = T::Future;
146
147 fn upgrade_outbound(self, socket: Stream, info: T::Info) -> Self::Future {
148 OutboundUpgradeSend::upgrade_outbound(self.0, socket, info)
149 }
150}
151
152impl<T: InboundUpgradeSend> upgrade::InboundUpgrade<Stream> for SendWrapper<T> {
153 type Output = T::Output;
154 type Error = T::Error;
155 type Future = T::Future;
156
157 fn upgrade_inbound(self, socket: Stream, info: T::Info) -> Self::Future {
158 InboundUpgradeSend::upgrade_inbound(self.0, socket, info)
159 }
160}