cs_mwc_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::NegotiatedSubstream;
22
23use futures::prelude::*;
24use mwc_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: upgrade::ProtocolName + 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: NegotiatedSubstream, info: Self::Info) -> Self::Future;
70}
71
72impl<T, TInfo> OutboundUpgradeSend for T
73where
74    T: upgrade::OutboundUpgrade<NegotiatedSubstream, Info = TInfo> + UpgradeInfoSend<Info = TInfo>,
75    TInfo: upgrade::ProtocolName + 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: NegotiatedSubstream, 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: NegotiatedSubstream, info: Self::Info) -> Self::Future;
104}
105
106impl<T, TInfo> InboundUpgradeSend for T
107where
108    T: upgrade::InboundUpgrade<NegotiatedSubstream, Info = TInfo> + UpgradeInfoSend<Info = TInfo>,
109    TInfo: upgrade::ProtocolName + 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: NegotiatedSubstream, 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<NegotiatedSubstream> 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: NegotiatedSubstream, info: T::Info) -> Self::Future {
146        OutboundUpgradeSend::upgrade_outbound(self.0, socket, info)
147    }
148}
149
150impl<T: InboundUpgradeSend> upgrade::InboundUpgrade<NegotiatedSubstream> 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: NegotiatedSubstream, info: T::Info) -> Self::Future {
156        InboundUpgradeSend::upgrade_inbound(self.0, socket, info)
157    }
158}