use crate::connection::ConnectedPoint;
use futures::prelude::*;
use multiaddr::Multiaddr;
use std::{error::Error, fmt};
pub mod and_then;
pub mod choice;
pub mod dummy;
pub mod map;
pub mod map_err;
pub mod memory;
pub mod timeout;
pub mod upgrade;
mod boxed;
mod optional;
pub use self::boxed::Boxed;
pub use self::choice::OrTransport;
pub use self::memory::MemoryTransport;
pub use self::optional::OptionalTransport;
pub use self::upgrade::Upgrade;
pub trait Transport {
type Output;
type Error: Error;
type Listener: Stream<
Item = Result<ListenerEvent<Self::ListenerUpgrade, Self::Error>, Self::Error>,
>;
type ListenerUpgrade: Future<Output = Result<Self::Output, Self::Error>>;
type Dial: Future<Output = Result<Self::Output, Self::Error>>;
fn listen_on(self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>>
where
Self: Sized;
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>>
where
Self: Sized;
fn dial_as_listener(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>>
where
Self: Sized;
fn address_translation(&self, listen: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr>;
fn boxed(self) -> boxed::Boxed<Self::Output>
where
Self: Transport + Sized + Clone + Send + Sync + 'static,
Self::Dial: Send + 'static,
Self::Listener: Send + 'static,
Self::ListenerUpgrade: Send + 'static,
Self::Error: Send + Sync,
{
boxed::boxed(self)
}
fn map<F, O>(self, f: F) -> map::Map<Self, F>
where
Self: Sized,
F: FnOnce(Self::Output, ConnectedPoint) -> O + Clone,
{
map::Map::new(self, f)
}
fn map_err<F, E>(self, f: F) -> map_err::MapErr<Self, F>
where
Self: Sized,
F: FnOnce(Self::Error) -> E + Clone,
{
map_err::MapErr::new(self, f)
}
fn or_transport<U>(self, other: U) -> OrTransport<Self, U>
where
Self: Sized,
U: Transport,
<U as Transport>::Error: 'static,
{
OrTransport::new(self, other)
}
fn and_then<C, F, O>(self, f: C) -> and_then::AndThen<Self, C>
where
Self: Sized,
C: FnOnce(Self::Output, ConnectedPoint) -> F + Clone,
F: TryFuture<Ok = O>,
<F as TryFuture>::Error: Error + 'static,
{
and_then::AndThen::new(self, f)
}
fn upgrade(self, version: upgrade::Version) -> upgrade::Builder<Self>
where
Self: Sized,
Self::Error: 'static,
{
upgrade::Builder::new(self, version)
}
}
#[derive(Clone, Debug, PartialEq)]
pub enum ListenerEvent<TUpgr, TErr> {
NewAddress(Multiaddr),
Upgrade {
upgrade: TUpgr,
local_addr: Multiaddr,
remote_addr: Multiaddr,
},
AddressExpired(Multiaddr),
Error(TErr),
}
impl<TUpgr, TErr> ListenerEvent<TUpgr, TErr> {
pub fn map<U>(self, f: impl FnOnce(TUpgr) -> U) -> ListenerEvent<U, TErr> {
match self {
ListenerEvent::Upgrade {
upgrade,
local_addr,
remote_addr,
} => ListenerEvent::Upgrade {
upgrade: f(upgrade),
local_addr,
remote_addr,
},
ListenerEvent::NewAddress(a) => ListenerEvent::NewAddress(a),
ListenerEvent::AddressExpired(a) => ListenerEvent::AddressExpired(a),
ListenerEvent::Error(e) => ListenerEvent::Error(e),
}
}
pub fn map_err<U>(self, f: impl FnOnce(TErr) -> U) -> ListenerEvent<TUpgr, U> {
match self {
ListenerEvent::Upgrade {
upgrade,
local_addr,
remote_addr,
} => ListenerEvent::Upgrade {
upgrade,
local_addr,
remote_addr,
},
ListenerEvent::NewAddress(a) => ListenerEvent::NewAddress(a),
ListenerEvent::AddressExpired(a) => ListenerEvent::AddressExpired(a),
ListenerEvent::Error(e) => ListenerEvent::Error(f(e)),
}
}
pub fn is_upgrade(&self) -> bool {
matches!(self, ListenerEvent::Upgrade { .. })
}
pub fn into_upgrade(self) -> Option<(TUpgr, Multiaddr)> {
if let ListenerEvent::Upgrade {
upgrade,
remote_addr,
..
} = self
{
Some((upgrade, remote_addr))
} else {
None
}
}
pub fn is_new_address(&self) -> bool {
matches!(self, ListenerEvent::NewAddress(_))
}
pub fn into_new_address(self) -> Option<Multiaddr> {
if let ListenerEvent::NewAddress(a) = self {
Some(a)
} else {
None
}
}
pub fn is_address_expired(&self) -> bool {
matches!(self, ListenerEvent::AddressExpired(_))
}
pub fn into_address_expired(self) -> Option<Multiaddr> {
if let ListenerEvent::AddressExpired(a) = self {
Some(a)
} else {
None
}
}
pub fn is_error(&self) -> bool {
matches!(self, ListenerEvent::Error(_))
}
pub fn into_error(self) -> Option<TErr> {
if let ListenerEvent::Error(err) = self {
Some(err)
} else {
None
}
}
}
#[derive(Debug, Clone)]
pub enum TransportError<TErr> {
MultiaddrNotSupported(Multiaddr),
Other(TErr),
}
impl<TErr> TransportError<TErr> {
pub fn map<TNewErr>(self, map: impl FnOnce(TErr) -> TNewErr) -> TransportError<TNewErr> {
match self {
TransportError::MultiaddrNotSupported(addr) => {
TransportError::MultiaddrNotSupported(addr)
}
TransportError::Other(err) => TransportError::Other(map(err)),
}
}
}
impl<TErr> fmt::Display for TransportError<TErr>
where
TErr: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TransportError::MultiaddrNotSupported(addr) => {
write!(f, "Multiaddr is not supported: {}", addr)
}
TransportError::Other(_) => Ok(()),
}
}
}
impl<TErr> Error for TransportError<TErr>
where
TErr: Error + 'static,
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
TransportError::MultiaddrNotSupported(_) => None,
TransportError::Other(err) => Some(err),
}
}
}