#[cfg(feature = "native-mux")]
use super::native_mux_impl;
#[cfg(feature = "process-mux")]
use std::ffi::OsStr;
use std::borrow::Cow;
use std::fmt;
use std::net::{self, SocketAddr};
use std::path::{Path, PathBuf};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ForwardType {
Local,
Remote,
}
#[cfg(feature = "native-mux")]
impl From<ForwardType> for native_mux_impl::ForwardType {
fn from(fwd_type: ForwardType) -> Self {
use native_mux_impl::ForwardType::*;
match fwd_type {
ForwardType::Local => Local,
ForwardType::Remote => Remote,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum Socket<'a> {
#[cfg(unix)]
#[cfg_attr(docsrs, doc(cfg(unix)))]
UnixSocket {
path: Cow<'a, Path>,
},
TcpSocket {
host: Cow<'a, str>,
port: u16,
},
}
impl From<SocketAddr> for Socket<'static> {
fn from(addr: SocketAddr) -> Self {
Socket::TcpSocket {
host: addr.ip().to_string().into(),
port: addr.port(),
}
}
}
macro_rules! impl_from_addr {
($ip:ty) => {
impl From<($ip, u16)> for Socket<'static> {
fn from((ip, port): ($ip, u16)) -> Self {
SocketAddr::new(ip.into(), port).into()
}
}
};
}
impl_from_addr!(net::IpAddr);
impl_from_addr!(net::Ipv4Addr);
impl_from_addr!(net::Ipv6Addr);
impl<'a> From<Cow<'a, Path>> for Socket<'a> {
fn from(path: Cow<'a, Path>) -> Self {
Socket::UnixSocket { path }
}
}
impl<'a> From<&'a Path> for Socket<'a> {
fn from(path: &'a Path) -> Self {
Socket::UnixSocket {
path: Cow::Borrowed(path),
}
}
}
impl From<PathBuf> for Socket<'static> {
fn from(path: PathBuf) -> Self {
Socket::UnixSocket {
path: Cow::Owned(path),
}
}
}
impl From<Box<Path>> for Socket<'static> {
fn from(path: Box<Path>) -> Self {
Socket::UnixSocket {
path: Cow::Owned(path.into()),
}
}
}
impl Socket<'_> {
pub fn new<'a, S>(host: S, port: u16) -> Socket<'a>
where
S: Into<Cow<'a, str>>,
{
Socket::TcpSocket {
host: host.into(),
port,
}
}
#[cfg(feature = "process-mux")]
pub(crate) fn as_os_str(&self) -> Cow<'_, OsStr> {
match self {
#[cfg(unix)]
Socket::UnixSocket { path } => Cow::Borrowed(path.as_os_str()),
Socket::TcpSocket { host, port } => Cow::Owned(format!("{host}:{port}").into()),
}
}
}
#[cfg(feature = "native-mux")]
impl<'a> From<Socket<'a>> for native_mux_impl::Socket<'a> {
fn from(socket: Socket<'a>) -> Self {
use native_mux_impl::Socket::*;
match socket {
#[cfg(unix)]
Socket::UnixSocket { path } => UnixSocket { path },
Socket::TcpSocket { host, port } => TcpSocket {
host,
port: port as u32,
},
}
}
}
impl<'a> fmt::Display for Socket<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
#[cfg(unix)]
Socket::UnixSocket { path } => {
write!(f, "{}", path.display())
}
Socket::TcpSocket { host, port } => write!(f, "{host}:{port}"),
}
}
}