mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-14 18:41:22 +00:00
Simplify handling of upgrade information. (#761)
This commit is contained in:
@ -18,7 +18,7 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{muxing::{Shutdown, StreamMuxer}, Multiaddr};
|
||||
use crate::{muxing::{Shutdown, StreamMuxer}, Multiaddr, ProtocolName};
|
||||
use futures::prelude::*;
|
||||
use std::{fmt, io::{Error as IoError, Read, Write}};
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
@ -342,3 +342,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum EitherName<A, B> { A(A), B(B) }
|
||||
|
||||
impl<A: ProtocolName, B: ProtocolName> ProtocolName for EitherName<A, B> {
|
||||
fn protocol_name(&self) -> &[u8] {
|
||||
match self {
|
||||
EitherName::A(a) => a.protocol_name(),
|
||||
EitherName::B(b) => b.protocol_name()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ pub use self::protocols_handler::{ProtocolsHandler, ProtocolsHandlerEvent};
|
||||
pub use self::public_key::PublicKey;
|
||||
pub use self::swarm::Swarm;
|
||||
pub use self::transport::Transport;
|
||||
pub use self::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo, UpgradeError};
|
||||
pub use self::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo, UpgradeError, ProtocolName};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Endpoint {
|
||||
|
@ -19,7 +19,7 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{
|
||||
Transport, Multiaddr, PublicKey, PeerId, InboundUpgrade, OutboundUpgrade, UpgradeInfo,
|
||||
Transport, Multiaddr, PublicKey, PeerId, InboundUpgrade, OutboundUpgrade, UpgradeInfo, ProtocolName,
|
||||
muxing::StreamMuxer,
|
||||
nodes::{
|
||||
handled_node::NodeHandler,
|
||||
@ -104,13 +104,15 @@ where TBehaviour: NetworkBehaviour<TTopology>,
|
||||
<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutEvent: Send + 'static,
|
||||
<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundOpenInfo: Send + 'static, // TODO: shouldn't be necessary
|
||||
<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol: InboundUpgrade<Substream<TMuxer>> + Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::NamesIter: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::UpgradeId: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::Info: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::InfoIter: Send + 'static,
|
||||
<<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as InboundUpgrade<Substream<TMuxer>>>::Error: fmt::Debug + Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as InboundUpgrade<Substream<TMuxer>>>::Future: Send + 'static,
|
||||
<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol: OutboundUpgrade<Substream<TMuxer>> + Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::NamesIter: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::UpgradeId: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::Info: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::InfoIter: Send + 'static,
|
||||
<<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as OutboundUpgrade<Substream<TMuxer>>>::Future: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as OutboundUpgrade<Substream<TMuxer>>>::Error: fmt::Debug + Send + 'static,
|
||||
<NodeHandlerWrapper<TBehaviour::ProtocolsHandler> as NodeHandler>::OutboundOpenInfo: Send + 'static, // TODO: shouldn't be necessary
|
||||
@ -122,8 +124,9 @@ where TBehaviour: NetworkBehaviour<TTopology>,
|
||||
let supported_protocols = behaviour
|
||||
.new_handler()
|
||||
.listen_protocol()
|
||||
.protocol_names()
|
||||
.map(|(name, _)| name.to_vec())
|
||||
.protocol_info()
|
||||
.into_iter()
|
||||
.map(|info| info.protocol_name().to_vec())
|
||||
.collect();
|
||||
|
||||
let local_peer_id = local_public_key.clone().into_peer_id();
|
||||
@ -222,13 +225,15 @@ where TBehaviour: NetworkBehaviour<TTopology>,
|
||||
<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol: InboundUpgrade<Substream<TMuxer>> + Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as InboundUpgrade<Substream<TMuxer>>>::Future: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as InboundUpgrade<Substream<TMuxer>>>::Error: fmt::Debug + Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::NamesIter: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::UpgradeId: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::Info: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::InfoIter: Send + 'static,
|
||||
<<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::InboundProtocol as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send + 'static,
|
||||
<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol: OutboundUpgrade<Substream<TMuxer>> + Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as OutboundUpgrade<Substream<TMuxer>>>::Future: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as OutboundUpgrade<Substream<TMuxer>>>::Error: fmt::Debug + Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::NamesIter: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::UpgradeId: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::Info: Send + 'static,
|
||||
<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::InfoIter: Send + 'static,
|
||||
<<<TBehaviour::ProtocolsHandler as ProtocolsHandler>::OutboundProtocol as UpgradeInfo>::InfoIter as IntoIterator>::IntoIter: Send + 'static,
|
||||
<NodeHandlerWrapper<TBehaviour::ProtocolsHandler> as NodeHandler>::OutboundOpenInfo: Send + 'static, // TODO: shouldn't be necessary
|
||||
TTopology: Topology,
|
||||
{
|
||||
@ -392,7 +397,7 @@ impl<'a, TTopology> PollParameters<'a, TTopology> {
|
||||
|
||||
/// Returns the public key of the local node.
|
||||
#[inline]
|
||||
pub fn local_public_key(&self) -> &PublicKey {
|
||||
pub fn local_public_key(&self) -> &PublicKey {
|
||||
self.local_public_key
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,8 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use bytes::Bytes;
|
||||
use crate::nodes::ConnectedPoint;
|
||||
use crate::upgrade::{UpgradeInfo, InboundUpgrade, OutboundUpgrade, UpgradeError};
|
||||
use crate::upgrade::{UpgradeInfo, InboundUpgrade, OutboundUpgrade, UpgradeError, ProtocolName};
|
||||
use futures::{future::Either, prelude::*};
|
||||
use multistream_select::{self, DialerSelectFuture, ListenerSelectFuture};
|
||||
use std::mem;
|
||||
@ -46,7 +45,8 @@ where
|
||||
C: AsyncRead + AsyncWrite,
|
||||
U: InboundUpgrade<C>,
|
||||
{
|
||||
let future = multistream_select::listener_select_proto(conn, UpgradeIntoProtocolsIterWrap(up));
|
||||
let iter = UpgradeInfoIterWrap(up);
|
||||
let future = multistream_select::listener_select_proto(conn, iter);
|
||||
InboundUpgradeApply {
|
||||
inner: InboundUpgradeApplyState::Init { future }
|
||||
}
|
||||
@ -58,7 +58,7 @@ where
|
||||
C: AsyncRead + AsyncWrite,
|
||||
U: OutboundUpgrade<C>
|
||||
{
|
||||
let iter = ProtocolNames(up.protocol_names());
|
||||
let iter = up.protocol_info().into_iter().map(NameWrap as fn(_) -> NameWrap<_>);
|
||||
let future = multistream_select::dialer_select_proto(conn, iter);
|
||||
OutboundUpgradeApply {
|
||||
inner: OutboundUpgradeApplyState::Init { future, upgrade: up }
|
||||
@ -80,7 +80,7 @@ where
|
||||
U: InboundUpgrade<C>
|
||||
{
|
||||
Init {
|
||||
future: ListenerSelectFuture<C, UpgradeIntoProtocolsIterWrap<U>, U::UpgradeId>,
|
||||
future: ListenerSelectFuture<C, UpgradeInfoIterWrap<U>, NameWrap<U::Info>>,
|
||||
},
|
||||
Upgrade {
|
||||
future: U::Future
|
||||
@ -100,7 +100,7 @@ where
|
||||
loop {
|
||||
match mem::replace(&mut self.inner, InboundUpgradeApplyState::Undefined) {
|
||||
InboundUpgradeApplyState::Init { mut future } => {
|
||||
let (upgrade_id, connection, upgrade) = match future.poll()? {
|
||||
let (info, connection, upgrade) = match future.poll()? {
|
||||
Async::Ready(x) => x,
|
||||
Async::NotReady => {
|
||||
self.inner = InboundUpgradeApplyState::Init { future };
|
||||
@ -108,7 +108,7 @@ where
|
||||
}
|
||||
};
|
||||
self.inner = InboundUpgradeApplyState::Upgrade {
|
||||
future: upgrade.0.upgrade_inbound(connection, upgrade_id)
|
||||
future: upgrade.0.upgrade_inbound(connection, info.0)
|
||||
};
|
||||
}
|
||||
InboundUpgradeApplyState::Upgrade { mut future } => {
|
||||
@ -149,7 +149,7 @@ where
|
||||
U: OutboundUpgrade<C>
|
||||
{
|
||||
Init {
|
||||
future: DialerSelectFuture<C, ProtocolNames<U::NamesIter>, U::UpgradeId>,
|
||||
future: DialerSelectFuture<C, NameWrapIter<<U::InfoIter as IntoIterator>::IntoIter>>,
|
||||
upgrade: U
|
||||
},
|
||||
Upgrade {
|
||||
@ -170,7 +170,7 @@ where
|
||||
loop {
|
||||
match mem::replace(&mut self.inner, OutboundUpgradeApplyState::Undefined) {
|
||||
OutboundUpgradeApplyState::Init { mut future, upgrade } => {
|
||||
let (upgrade_id, connection) = match future.poll()? {
|
||||
let (info, connection) = match future.poll()? {
|
||||
Async::Ready(x) => x,
|
||||
Async::NotReady => {
|
||||
self.inner = OutboundUpgradeApplyState::Init { future, upgrade };
|
||||
@ -178,7 +178,7 @@ where
|
||||
}
|
||||
};
|
||||
self.inner = OutboundUpgradeApplyState::Upgrade {
|
||||
future: upgrade.upgrade_outbound(connection, upgrade_id)
|
||||
future: upgrade.upgrade_outbound(connection, info.0)
|
||||
};
|
||||
}
|
||||
OutboundUpgradeApplyState::Upgrade { mut future } => {
|
||||
@ -205,37 +205,29 @@ where
|
||||
}
|
||||
|
||||
/// Wraps around a `UpgradeInfo` and satisfies the requirement of `listener_select_proto`.
|
||||
struct UpgradeIntoProtocolsIterWrap<U>(U);
|
||||
struct UpgradeInfoIterWrap<U>(U);
|
||||
|
||||
impl<'a, U> IntoIterator for &'a UpgradeIntoProtocolsIterWrap<U>
|
||||
where U: UpgradeInfo
|
||||
{
|
||||
type Item = (Bytes, fn(&Bytes, &Bytes) -> bool, U::UpgradeId);
|
||||
type IntoIter = ProtocolNames<U::NamesIter>;
|
||||
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
ProtocolNames(self.0.protocol_names())
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator adapter which adds equality matching predicates to items.
|
||||
/// Used in `NegotiationFuture`.
|
||||
#[derive(Clone)]
|
||||
pub struct ProtocolNames<I>(I);
|
||||
|
||||
impl<I, Id> Iterator for ProtocolNames<I>
|
||||
impl<'a, U> IntoIterator for &'a UpgradeInfoIterWrap<U>
|
||||
where
|
||||
I: Iterator<Item=(Bytes, Id)>
|
||||
U: UpgradeInfo
|
||||
{
|
||||
type Item = (Bytes, fn(&Bytes, &Bytes) -> bool, Id);
|
||||
type Item = NameWrap<U::Info>;
|
||||
type IntoIter = NameWrapIter<<U::InfoIter as IntoIterator>::IntoIter>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let f = <Bytes as PartialEq>::eq as fn(&Bytes, &Bytes) -> bool;
|
||||
self.0.next().map(|(b, id)| (b, f, id))
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.0.size_hint()
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.protocol_info().into_iter().map(NameWrap)
|
||||
}
|
||||
}
|
||||
|
||||
type NameWrapIter<I> =
|
||||
std::iter::Map<I, fn(<I as Iterator>::Item) -> NameWrap<<I as Iterator>::Item>>;
|
||||
|
||||
/// Wrapper type to expose an `AsRef<[u8]>` impl for all types implementing `ProtocolName`.
|
||||
struct NameWrap<N>(N);
|
||||
|
||||
impl<N: ProtocolName> AsRef<[u8]> for NameWrap<N> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.protocol_name()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,10 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use bytes::Bytes;
|
||||
use crate::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo};
|
||||
use futures::future;
|
||||
use std::iter;
|
||||
use void::{unreachable, Void};
|
||||
use void::Void;
|
||||
|
||||
/// Dummy implementation of `UpgradeInfo`/`InboundUpgrade`/`OutboundUpgrade` that doesn't support
|
||||
/// any protocol.
|
||||
@ -30,10 +29,10 @@ use void::{unreachable, Void};
|
||||
pub struct DeniedUpgrade;
|
||||
|
||||
impl UpgradeInfo for DeniedUpgrade {
|
||||
type UpgradeId = Void;
|
||||
type NamesIter = iter::Empty<(Bytes, Self::UpgradeId)>;
|
||||
type Info = &'static [u8];
|
||||
type InfoIter = iter::Empty<Self::Info>;
|
||||
|
||||
fn protocol_names(&self) -> Self::NamesIter {
|
||||
fn protocol_info(&self) -> Self::InfoIter {
|
||||
iter::empty()
|
||||
}
|
||||
}
|
||||
@ -43,8 +42,8 @@ impl<C> InboundUpgrade<C> for DeniedUpgrade {
|
||||
type Error = Void;
|
||||
type Future = future::Empty<Self::Output, Self::Error>;
|
||||
|
||||
fn upgrade_inbound(self, _: C, id: Self::UpgradeId) -> Self::Future {
|
||||
unreachable(id)
|
||||
fn upgrade_inbound(self, _: C, _: Self::Info) -> Self::Future {
|
||||
future::empty()
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,8 +52,8 @@ impl<C> OutboundUpgrade<C> for DeniedUpgrade {
|
||||
type Error = Void;
|
||||
type Future = future::Empty<Self::Output, Self::Error>;
|
||||
|
||||
fn upgrade_outbound(self, _: C, id: Self::UpgradeId) -> Self::Future {
|
||||
unreachable(id)
|
||||
fn upgrade_outbound(self, _: C, _: Self::Info) -> Self::Future {
|
||||
future::empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,8 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::future::Either;
|
||||
use crate::{
|
||||
either::{EitherOutput, EitherError, EitherFuture2},
|
||||
either::{EitherOutput, EitherError, EitherFuture2, EitherName},
|
||||
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}
|
||||
};
|
||||
|
||||
@ -34,13 +32,16 @@ where
|
||||
A: UpgradeInfo,
|
||||
B: UpgradeInfo
|
||||
{
|
||||
type UpgradeId = Either<A::UpgradeId, B::UpgradeId>;
|
||||
type NamesIter = EitherIter<A::NamesIter, B::NamesIter>;
|
||||
type Info = EitherName<A::Info, B::Info>;
|
||||
type InfoIter = EitherIter<
|
||||
<A::InfoIter as IntoIterator>::IntoIter,
|
||||
<B::InfoIter as IntoIterator>::IntoIter
|
||||
>;
|
||||
|
||||
fn protocol_names(&self) -> Self::NamesIter {
|
||||
fn protocol_info(&self) -> Self::InfoIter {
|
||||
match self {
|
||||
EitherUpgrade::A(a) => EitherIter::A(a.protocol_names()),
|
||||
EitherUpgrade::B(b) => EitherIter::B(b.protocol_names())
|
||||
EitherUpgrade::A(a) => EitherIter::A(a.protocol_info().into_iter()),
|
||||
EitherUpgrade::B(b) => EitherIter::B(b.protocol_info().into_iter())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,10 +55,10 @@ where
|
||||
type Error = EitherError<EA, EB>;
|
||||
type Future = EitherFuture2<A::Future, B::Future>;
|
||||
|
||||
fn upgrade_inbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
match (self, id) {
|
||||
(EitherUpgrade::A(a), Either::A(id)) => EitherFuture2::A(a.upgrade_inbound(sock, id)),
|
||||
(EitherUpgrade::B(b), Either::B(id)) => EitherFuture2::B(b.upgrade_inbound(sock, id)),
|
||||
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
match (self, info) {
|
||||
(EitherUpgrade::A(a), EitherName::A(info)) => EitherFuture2::A(a.upgrade_inbound(sock, info)),
|
||||
(EitherUpgrade::B(b), EitherName::B(info)) => EitherFuture2::B(b.upgrade_inbound(sock, info)),
|
||||
_ => panic!("Invalid invocation of EitherUpgrade::upgrade_inbound")
|
||||
}
|
||||
}
|
||||
@ -72,10 +73,10 @@ where
|
||||
type Error = EitherError<EA, EB>;
|
||||
type Future = EitherFuture2<A::Future, B::Future>;
|
||||
|
||||
fn upgrade_outbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
match (self, id) {
|
||||
(EitherUpgrade::A(a), Either::A(id)) => EitherFuture2::A(a.upgrade_outbound(sock, id)),
|
||||
(EitherUpgrade::B(b), Either::B(id)) => EitherFuture2::B(b.upgrade_outbound(sock, id)),
|
||||
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
match (self, info) {
|
||||
(EitherUpgrade::A(a), EitherName::A(info)) => EitherFuture2::A(a.upgrade_outbound(sock, info)),
|
||||
(EitherUpgrade::B(b), EitherName::B(info)) => EitherFuture2::B(b.upgrade_outbound(sock, info)),
|
||||
_ => panic!("Invalid invocation of EitherUpgrade::upgrade_outbound")
|
||||
}
|
||||
}
|
||||
@ -85,17 +86,17 @@ where
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum EitherIter<A, B> { A(A), B(B) }
|
||||
|
||||
impl<A, B, AId, BId> Iterator for EitherIter<A, B>
|
||||
impl<A, B> Iterator for EitherIter<A, B>
|
||||
where
|
||||
A: Iterator<Item = (Bytes, AId)>,
|
||||
B: Iterator<Item = (Bytes, BId)>,
|
||||
A: Iterator,
|
||||
B: Iterator
|
||||
{
|
||||
type Item = (Bytes, Either<AId, BId>);
|
||||
type Item = EitherName<A::Item, B::Item>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self {
|
||||
EitherIter::A(a) => a.next().map(|(name, id)| (name, Either::A(id))),
|
||||
EitherIter::B(b) => b.next().map(|(name, id)| (name, Either::B(id)))
|
||||
EitherIter::A(a) => a.next().map(EitherName::A),
|
||||
EitherIter::B(b) => b.next().map(EitherName::B)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,11 +35,11 @@ impl<U, F> UpgradeInfo for MapInboundUpgrade<U, F>
|
||||
where
|
||||
U: UpgradeInfo
|
||||
{
|
||||
type UpgradeId = U::UpgradeId;
|
||||
type NamesIter = U::NamesIter;
|
||||
type Info = U::Info;
|
||||
type InfoIter = U::InfoIter;
|
||||
|
||||
fn protocol_names(&self) -> Self::NamesIter {
|
||||
self.upgrade.protocol_names()
|
||||
fn protocol_info(&self) -> Self::InfoIter {
|
||||
self.upgrade.protocol_info()
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,9 +52,9 @@ where
|
||||
type Error = U::Error;
|
||||
type Future = MapFuture<U::Future, F>;
|
||||
|
||||
fn upgrade_inbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
MapFuture {
|
||||
inner: self.upgrade.upgrade_inbound(sock, id),
|
||||
inner: self.upgrade.upgrade_inbound(sock, info),
|
||||
map: Some(self.fun)
|
||||
}
|
||||
}
|
||||
@ -68,8 +68,8 @@ where
|
||||
type Error = U::Error;
|
||||
type Future = U::Future;
|
||||
|
||||
fn upgrade_outbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
self.upgrade.upgrade_outbound(sock, id)
|
||||
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
self.upgrade.upgrade_outbound(sock, info)
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,11 +87,11 @@ impl<U, F> UpgradeInfo for MapOutboundUpgrade<U, F>
|
||||
where
|
||||
U: UpgradeInfo
|
||||
{
|
||||
type UpgradeId = U::UpgradeId;
|
||||
type NamesIter = U::NamesIter;
|
||||
type Info = U::Info;
|
||||
type InfoIter = U::InfoIter;
|
||||
|
||||
fn protocol_names(&self) -> Self::NamesIter {
|
||||
self.upgrade.protocol_names()
|
||||
fn protocol_info(&self) -> Self::InfoIter {
|
||||
self.upgrade.protocol_info()
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,8 +103,8 @@ where
|
||||
type Error = U::Error;
|
||||
type Future = U::Future;
|
||||
|
||||
fn upgrade_inbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
self.upgrade.upgrade_inbound(sock, id)
|
||||
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
self.upgrade.upgrade_inbound(sock, info)
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,9 +117,9 @@ where
|
||||
type Error = U::Error;
|
||||
type Future = MapFuture<U::Future, F>;
|
||||
|
||||
fn upgrade_outbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
MapFuture {
|
||||
inner: self.upgrade.upgrade_outbound(sock, id),
|
||||
inner: self.upgrade.upgrade_outbound(sock, info),
|
||||
map: Some(self.fun)
|
||||
}
|
||||
}
|
||||
@ -139,11 +139,11 @@ impl<U, F> UpgradeInfo for MapInboundUpgradeErr<U, F>
|
||||
where
|
||||
U: UpgradeInfo
|
||||
{
|
||||
type UpgradeId = U::UpgradeId;
|
||||
type NamesIter = U::NamesIter;
|
||||
type Info = U::Info;
|
||||
type InfoIter = U::InfoIter;
|
||||
|
||||
fn protocol_names(&self) -> Self::NamesIter {
|
||||
self.upgrade.protocol_names()
|
||||
fn protocol_info(&self) -> Self::InfoIter {
|
||||
self.upgrade.protocol_info()
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,9 +156,9 @@ where
|
||||
type Error = T;
|
||||
type Future = MapErrFuture<U::Future, F>;
|
||||
|
||||
fn upgrade_inbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
MapErrFuture {
|
||||
fut: self.upgrade.upgrade_inbound(sock, id),
|
||||
fut: self.upgrade.upgrade_inbound(sock, info),
|
||||
fun: Some(self.fun)
|
||||
}
|
||||
}
|
||||
@ -172,8 +172,8 @@ where
|
||||
type Error = U::Error;
|
||||
type Future = U::Future;
|
||||
|
||||
fn upgrade_outbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
self.upgrade.upgrade_outbound(sock, id)
|
||||
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
self.upgrade.upgrade_outbound(sock, info)
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,11 +191,11 @@ impl<U, F> UpgradeInfo for MapOutboundUpgradeErr<U, F>
|
||||
where
|
||||
U: UpgradeInfo
|
||||
{
|
||||
type UpgradeId = U::UpgradeId;
|
||||
type NamesIter = U::NamesIter;
|
||||
type Info = U::Info;
|
||||
type InfoIter = U::InfoIter;
|
||||
|
||||
fn protocol_names(&self) -> Self::NamesIter {
|
||||
self.upgrade.protocol_names()
|
||||
fn protocol_info(&self) -> Self::InfoIter {
|
||||
self.upgrade.protocol_info()
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,9 +208,9 @@ where
|
||||
type Error = T;
|
||||
type Future = MapErrFuture<U::Future, F>;
|
||||
|
||||
fn upgrade_outbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
MapErrFuture {
|
||||
fut: self.upgrade.upgrade_outbound(sock, id),
|
||||
fut: self.upgrade.upgrade_outbound(sock, info),
|
||||
fun: Some(self.fun)
|
||||
}
|
||||
}
|
||||
@ -224,8 +224,8 @@ where
|
||||
type Error = U::Error;
|
||||
type Future = U::Future;
|
||||
|
||||
fn upgrade_inbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
self.upgrade.upgrade_inbound(sock, id)
|
||||
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
self.upgrade.upgrade_inbound(sock, info)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
//!
|
||||
//! An upgrade is performed in two steps:
|
||||
//!
|
||||
//! - A protocol negotiation step. The `UpgradeInfo::protocol_names` method is called to determine
|
||||
//! - A protocol negotiation step. The `UpgradeInfo::protocol_info` method is called to determine
|
||||
//! which protocols are supported by the trait implementation. The `multistream-select` protocol
|
||||
//! is used in order to agree on which protocol to use amongst the ones supported.
|
||||
//!
|
||||
@ -64,7 +64,6 @@ mod error;
|
||||
mod map;
|
||||
mod select;
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::future::Future;
|
||||
|
||||
pub use self::{
|
||||
@ -76,18 +75,28 @@ pub use self::{
|
||||
select::SelectUpgrade
|
||||
};
|
||||
|
||||
/// Types serving as protocol names.
|
||||
pub trait ProtocolName {
|
||||
/// The protocol name as bytes.
|
||||
fn protocol_name(&self) -> &[u8];
|
||||
}
|
||||
|
||||
impl<T: AsRef<[u8]>> ProtocolName for T {
|
||||
fn protocol_name(&self) -> &[u8] {
|
||||
self.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
/// Common trait for upgrades that can be applied on inbound substreams, outbound substreams,
|
||||
/// or both.
|
||||
pub trait UpgradeInfo {
|
||||
/// Opaque type representing a negotiable protocol.
|
||||
type UpgradeId;
|
||||
/// Iterator returned by `protocol_names`.
|
||||
type NamesIter: Iterator<Item = (Bytes, Self::UpgradeId)>;
|
||||
type Info: ProtocolName;
|
||||
/// Iterator returned by `protocol_info`.
|
||||
type InfoIter: IntoIterator<Item = Self::Info>;
|
||||
|
||||
/// Returns the list of protocols that are supported. Used during the negotiation process.
|
||||
///
|
||||
/// Each item returned by the iterator is a pair of a protocol name and an opaque identifier.
|
||||
fn protocol_names(&self) -> Self::NamesIter;
|
||||
fn protocol_info(&self) -> Self::InfoIter;
|
||||
}
|
||||
|
||||
/// Possible upgrade on an inbound connection or substream.
|
||||
@ -102,8 +111,8 @@ pub trait InboundUpgrade<C>: UpgradeInfo {
|
||||
/// After we have determined that the remote supports one of the protocols we support, this
|
||||
/// method is called to start the handshake.
|
||||
///
|
||||
/// The `id` is the identifier of the protocol, as produced by `protocol_names()`.
|
||||
fn upgrade_inbound(self, socket: C, id: Self::UpgradeId) -> Self::Future;
|
||||
/// The `info` is the identifier of the protocol, as produced by `protocol_info`.
|
||||
fn upgrade_inbound(self, socket: C, info: Self::Info) -> Self::Future;
|
||||
}
|
||||
|
||||
/// Extension trait for `InboundUpgrade`. Automatically implemented on all types that implement
|
||||
@ -142,8 +151,8 @@ pub trait OutboundUpgrade<C>: UpgradeInfo {
|
||||
/// After we have determined that the remote supports one of the protocols we support, this
|
||||
/// method is called to start the handshake.
|
||||
///
|
||||
/// The `id` is the identifier of the protocol, as produced by `protocol_names()`.
|
||||
fn upgrade_outbound(self, socket: C, id: Self::UpgradeId) -> Self::Future;
|
||||
/// The `info` is the identifier of the protocol, as produced by `protocol_info`.
|
||||
fn upgrade_outbound(self, socket: C, info: Self::Info) -> Self::Future;
|
||||
}
|
||||
|
||||
/// Extention trait for `OutboundUpgrade`. Automatically implemented on all types that implement
|
||||
|
@ -18,10 +18,8 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::future::Either;
|
||||
use crate::{
|
||||
either::{EitherOutput, EitherError, EitherFuture2},
|
||||
either::{EitherOutput, EitherError, EitherFuture2, EitherName},
|
||||
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}
|
||||
};
|
||||
|
||||
@ -46,11 +44,14 @@ where
|
||||
A: UpgradeInfo,
|
||||
B: UpgradeInfo
|
||||
{
|
||||
type UpgradeId = Either<A::UpgradeId, B::UpgradeId>;
|
||||
type NamesIter = NamesIterChain<A::NamesIter, B::NamesIter>;
|
||||
type Info = EitherName<A::Info, B::Info>;
|
||||
type InfoIter = InfoIterChain<
|
||||
<A::InfoIter as IntoIterator>::IntoIter,
|
||||
<B::InfoIter as IntoIterator>::IntoIter
|
||||
>;
|
||||
|
||||
fn protocol_names(&self) -> Self::NamesIter {
|
||||
NamesIterChain(self.0.protocol_names(), self.1.protocol_names())
|
||||
fn protocol_info(&self) -> Self::InfoIter {
|
||||
InfoIterChain(self.0.protocol_info().into_iter(), self.1.protocol_info().into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,10 +64,10 @@ where
|
||||
type Error = EitherError<EA, EB>;
|
||||
type Future = EitherFuture2<A::Future, B::Future>;
|
||||
|
||||
fn upgrade_inbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
match id {
|
||||
Either::A(id) => EitherFuture2::A(self.0.upgrade_inbound(sock, id)),
|
||||
Either::B(id) => EitherFuture2::B(self.1.upgrade_inbound(sock, id))
|
||||
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
match info {
|
||||
EitherName::A(info) => EitherFuture2::A(self.0.upgrade_inbound(sock, info)),
|
||||
EitherName::B(info) => EitherFuture2::B(self.1.upgrade_inbound(sock, info))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -80,31 +81,31 @@ where
|
||||
type Error = EitherError<EA, EB>;
|
||||
type Future = EitherFuture2<A::Future, B::Future>;
|
||||
|
||||
fn upgrade_outbound(self, sock: C, id: Self::UpgradeId) -> Self::Future {
|
||||
match id {
|
||||
Either::A(id) => EitherFuture2::A(self.0.upgrade_outbound(sock, id)),
|
||||
Either::B(id) => EitherFuture2::B(self.1.upgrade_outbound(sock, id))
|
||||
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
|
||||
match info {
|
||||
EitherName::A(info) => EitherFuture2::A(self.0.upgrade_outbound(sock, info)),
|
||||
EitherName::B(info) => EitherFuture2::B(self.1.upgrade_outbound(sock, info))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator that combines the protocol names of twp upgrades.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NamesIterChain<A, B>(A, B);
|
||||
pub struct InfoIterChain<A, B>(A, B);
|
||||
|
||||
impl<A, B, AId, BId> Iterator for NamesIterChain<A, B>
|
||||
impl<A, B> Iterator for InfoIterChain<A, B>
|
||||
where
|
||||
A: Iterator<Item = (Bytes, AId)>,
|
||||
B: Iterator<Item = (Bytes, BId)>,
|
||||
A: Iterator,
|
||||
B: Iterator
|
||||
{
|
||||
type Item = (Bytes, Either<AId, BId>);
|
||||
type Item = EitherName<A::Item, B::Item>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if let Some((name, id)) = self.0.next() {
|
||||
return Some((name, Either::A(id)))
|
||||
if let Some(info) = self.0.next() {
|
||||
return Some(EitherName::A(info))
|
||||
}
|
||||
if let Some((name, id)) = self.1.next() {
|
||||
return Some((name, Either::B(id)))
|
||||
if let Some(info) = self.1.next() {
|
||||
return Some(EitherName::B(info))
|
||||
}
|
||||
None
|
||||
}
|
||||
|
Reference in New Issue
Block a user