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}