Fix mapping of upgrade. (#654)

The current implementation of `MapUpgrade` implements `InboundUpgrade`
and `OutboundUpgrade` and applies the transformation in both cases which
means that mapping is always applied to inbound and outbound upgrades.
This commit uses separate `MapInboundUpgrade` and `MapOutboundUpgrade`
types which implements both traits but only map in one direction.
This commit is contained in:
Toralf Wittner
2018-11-19 10:58:45 +01:00
committed by GitHub
parent 2c1807b646
commit 1d1970c772
3 changed files with 65 additions and 15 deletions

View File

@ -771,7 +771,7 @@ where
upgrade::OrUpgrade< upgrade::OrUpgrade<
upgrade::Toggleable< upgrade::Toggleable<
upgrade::MapUpgradeErr< upgrade::MapUpgradeErr<
upgrade::MapUpgrade< upgrade::MapInboundUpgrade<
TProto1::InboundProtocol, TProto1::InboundProtocol,
fn(TProto1Out) -> EitherOutput<TProto1Out, TProto2Out> fn(TProto1Out) -> EitherOutput<TProto1Out, TProto2Out>
>, >,
@ -784,7 +784,7 @@ where
>, >,
upgrade::Toggleable< upgrade::Toggleable<
upgrade::MapUpgradeErr< upgrade::MapUpgradeErr<
upgrade::MapUpgrade< upgrade::MapInboundUpgrade<
TProto2::InboundProtocol, TProto2::InboundProtocol,
fn(TProto2Out) -> EitherOutput<TProto1Out, TProto2Out> fn(TProto2Out) -> EitherOutput<TProto1Out, TProto2Out>
>, >,
@ -801,7 +801,7 @@ where
upgrade::OrUpgrade< upgrade::OrUpgrade<
upgrade::Toggleable< upgrade::Toggleable<
upgrade::MapUpgradeErr< upgrade::MapUpgradeErr<
upgrade::MapUpgrade< upgrade::MapOutboundUpgrade<
TProto1::OutboundProtocol, TProto1::OutboundProtocol,
fn(TProto1Out) -> EitherOutput<TProto1Out, TProto2Out> fn(TProto1Out) -> EitherOutput<TProto1Out, TProto2Out>
>, >,
@ -814,7 +814,7 @@ where
>, >,
upgrade::Toggleable< upgrade::Toggleable<
upgrade::MapUpgradeErr< upgrade::MapUpgradeErr<
upgrade::MapUpgrade< upgrade::MapOutboundUpgrade<
TProto2::OutboundProtocol, TProto2::OutboundProtocol,
fn(TProto2Out) -> EitherOutput<TProto1Out, TProto2Out> fn(TProto2Out) -> EitherOutput<TProto1Out, TProto2Out>
>, >,

View File

@ -23,15 +23,15 @@ use crate::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo};
/// Wraps around an upgrade and applies a closure to the output. /// Wraps around an upgrade and applies a closure to the output.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MapUpgrade<U, F> { upgrade: U, fun: F } pub struct MapInboundUpgrade<U, F> { upgrade: U, fun: F }
impl<U, F> MapUpgrade<U, F> { impl<U, F> MapInboundUpgrade<U, F> {
pub fn new(upgrade: U, fun: F) -> Self { pub fn new(upgrade: U, fun: F) -> Self {
MapUpgrade { upgrade, fun } MapInboundUpgrade { upgrade, fun }
} }
} }
impl<U, F> UpgradeInfo for MapUpgrade<U, F> impl<U, F> UpgradeInfo for MapInboundUpgrade<U, F>
where where
U: UpgradeInfo U: UpgradeInfo
{ {
@ -43,7 +43,7 @@ where
} }
} }
impl<C, U, F, T> InboundUpgrade<C> for MapUpgrade<U, F> impl<C, U, F, T> InboundUpgrade<C> for MapInboundUpgrade<U, F>
where where
U: InboundUpgrade<C>, U: InboundUpgrade<C>,
F: FnOnce(U::Output) -> T F: FnOnce(U::Output) -> T
@ -60,7 +60,57 @@ where
} }
} }
impl<C, U, F, T> OutboundUpgrade<C> for MapUpgrade<U, F> impl<C, U, F, T> OutboundUpgrade<C> for MapInboundUpgrade<U, F>
where
U: OutboundUpgrade<C>,
F: FnOnce(U::Output) -> T
{
type Output = U::Output;
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)
}
}
/// Wraps around an upgrade and applies a closure to the output.
#[derive(Debug, Clone)]
pub struct MapOutboundUpgrade<U, F> { upgrade: U, fun: F }
impl<U, F> MapOutboundUpgrade<U, F> {
pub fn new(upgrade: U, fun: F) -> Self {
MapOutboundUpgrade { upgrade, fun }
}
}
impl<U, F> UpgradeInfo for MapOutboundUpgrade<U, F>
where
U: UpgradeInfo
{
type UpgradeId = U::UpgradeId;
type NamesIter = U::NamesIter;
fn protocol_names(&self) -> Self::NamesIter {
self.upgrade.protocol_names()
}
}
impl<C, U, F, T> InboundUpgrade<C> for MapOutboundUpgrade<U, F>
where
U: InboundUpgrade<C>,
F: FnOnce(U::Output) -> T
{
type Output = U::Output;
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)
}
}
impl<C, U, F, T> OutboundUpgrade<C> for MapOutboundUpgrade<U, F>
where where
U: OutboundUpgrade<C>, U: OutboundUpgrade<C>,
F: FnOnce(U::Output) -> T F: FnOnce(U::Output) -> T

View File

@ -71,7 +71,7 @@ pub use self::{
apply::{apply_inbound, apply_outbound, InboundUpgradeApply, OutboundUpgradeApply}, apply::{apply_inbound, apply_outbound, InboundUpgradeApply, OutboundUpgradeApply},
denied::DeniedUpgrade, denied::DeniedUpgrade,
error::UpgradeError, error::UpgradeError,
map::{MapUpgrade, MapUpgradeErr}, map::{MapInboundUpgrade, MapOutboundUpgrade, MapUpgradeErr},
or::OrUpgrade, or::OrUpgrade,
toggleable::{toggleable, Toggleable} toggleable::{toggleable, Toggleable}
}; };
@ -110,12 +110,12 @@ pub trait InboundUpgrade<C>: UpgradeInfo {
/// `InboundUpgrade`. /// `InboundUpgrade`.
pub trait InboundUpgradeExt<C>: InboundUpgrade<C> { pub trait InboundUpgradeExt<C>: InboundUpgrade<C> {
/// Returns a new object that wraps around `Self` and applies a closure to the `Output`. /// Returns a new object that wraps around `Self` and applies a closure to the `Output`.
fn map_inbound<F, T>(self, f: F) -> MapUpgrade<Self, F> fn map_inbound<F, T>(self, f: F) -> MapInboundUpgrade<Self, F>
where where
Self: Sized, Self: Sized,
F: FnOnce(Self::Output) -> T F: FnOnce(Self::Output) -> T
{ {
MapUpgrade::new(self, f) MapInboundUpgrade::new(self, f)
} }
/// Returns a new object that wraps around `Self` and applies a closure to the `Error`. /// Returns a new object that wraps around `Self` and applies a closure to the `Error`.
@ -160,12 +160,12 @@ pub trait OutboundUpgrade<C>: UpgradeInfo {
/// `OutboundUpgrade`. /// `OutboundUpgrade`.
pub trait OutboundUpgradeExt<C>: OutboundUpgrade<C> { pub trait OutboundUpgradeExt<C>: OutboundUpgrade<C> {
/// Returns a new object that wraps around `Self` and applies a closure to the `Output`. /// Returns a new object that wraps around `Self` and applies a closure to the `Output`.
fn map_outbound<F, T>(self, f: F) -> MapUpgrade<Self, F> fn map_outbound<F, T>(self, f: F) -> MapOutboundUpgrade<Self, F>
where where
Self: Sized, Self: Sized,
F: FnOnce(Self::Output) -> T F: FnOnce(Self::Output) -> T
{ {
MapUpgrade::new(self, f) MapOutboundUpgrade::new(self, f)
} }
/// Returns a new object that wraps around `Self` and applies a closure to the `Error`. /// Returns a new object that wraps around `Self` and applies a closure to the `Error`.