Started: Combined Unix + Tcp socket and listener sock::Listener, sock::Stream

Fortune for transfer's current commit: Blessing − 吉
master
Avril 3 years ago
parent d0b58f6140
commit 7a8b5e669d
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,6 +1,7 @@
//! Socket handling
use super::*;
use std::str;
use std::io;
use std::path::{
Path, PathBuf
};
@ -31,6 +32,25 @@ pub enum SocketAddr
IP(std::net::SocketAddr),
}
impl TryFrom<tokio::net::unix::SocketAddr> for SocketAddrUnix
{
type Error = AddrParseError;
fn try_from(from: tokio::net::unix::SocketAddr) -> Result<Self, Self::Error>
{
from.as_pathname().ok_or(AddrParseError).map(|path| Self{path: path.into()})
}
}
impl From<SocketAddrUnix> for SocketAddr
{
fn from(from: SocketAddrUnix) -> Self
{
Self::Unix(from)
}
}
impl From<std::net::SocketAddr> for SocketAddr
{
fn from(from: std::net::SocketAddr) -> Self
@ -62,3 +82,79 @@ impl str::FromStr for SocketAddr
}
}
#[derive(Debug)]
enum ListenerInner
{
Unix(tokio::net::UnixListener),
Tcp(tokio::net::TcpListener),
}
#[derive(Debug)]
enum StreamInner
{
Unix(tokio::net::UnixStream),
Tcp(tokio::net::TcpStream),
}
impl ListenerInner
{
fn con_unix(sock: &SocketAddrUnix) -> io::Result<Self>
{
tokio::net::UnixListener::bind(&sock.path).map(Self::Unix)
}
async fn con_tcp(sock: &std::net::SocketAddr) -> io::Result<Self>
{
tokio::net::TcpListener::bind(sock).await.map(Self::Tcp)
}
}
/// A connected socket.
//TODO: Stream::connect(), direct connection
#[derive(Debug)]
pub struct Stream(Box<StreamInner>, SocketAddr);
impl From<(tokio::net::UnixStream, tokio::net::unix::SocketAddr)> for Stream
{
fn from((s, a): (tokio::net::UnixStream, tokio::net::unix::SocketAddr)) -> Self
{
Self(Box::new(StreamInner::Unix(s)), SocketAddrUnix::try_from(a).unwrap().into())
}
}
impl From<(tokio::net::TcpStream, std::net::SocketAddr)> for Stream
{
fn from((s, a): (tokio::net::TcpStream, std::net::SocketAddr)) -> Self
{
Self(Box::new(StreamInner::Tcp(s)), a.into())
}
}
/// A network listener, for either a Unix socket or TCP socket.
#[derive(Debug)]
pub struct Listener(Box<ListenerInner>);
impl Listener
{
/// Bind to Unix socket or IP/port.
///
/// Completes immediately when binding unix socket
pub async fn bind(sock: impl Into<SocketAddr>) -> io::Result<Self>
{
match sock.into() {
SocketAddr::Unix(ref unix) => ListenerInner::con_unix(unix).map(Box::new),
SocketAddr::IP(ref tcp) => ListenerInner::con_tcp(tcp).await.map(Box::new),
}.map(Self)
}
/// Accept connection on this listener.
pub async fn accept(&self) -> io::Result<Stream>
{
match self.0.as_ref()
{
ListenerInner::Unix(un) => un.accept().await.map(Into::into),
ListenerInner::Tcp(tcp) => tcp.accept().await.map(Into::into),
}
}
}
//TODO: impl Stream

Loading…
Cancel
Save