Skip to main content

requiem_server/
socket.rs

1use std::{fmt, io, net};
2
3use requiem_codec::{AsyncRead, AsyncWrite};
4use requiem_rt::net::TcpStream;
5
6pub(crate) enum StdListener {
7    Tcp(net::TcpListener),
8    #[cfg(all(unix))]
9    Uds(std::os::unix::net::UnixListener),
10}
11
12pub(crate) enum SocketAddr {
13    Tcp(net::SocketAddr),
14    #[cfg(all(unix))]
15    Uds(std::os::unix::net::SocketAddr),
16}
17
18impl fmt::Display for SocketAddr {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        match *self {
21            SocketAddr::Tcp(ref addr) => write!(f, "{}", addr),
22            #[cfg(all(unix))]
23            SocketAddr::Uds(ref addr) => write!(f, "{:?}", addr),
24        }
25    }
26}
27
28impl fmt::Debug for SocketAddr {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        match *self {
31            SocketAddr::Tcp(ref addr) => write!(f, "{:?}", addr),
32            #[cfg(all(unix))]
33            SocketAddr::Uds(ref addr) => write!(f, "{:?}", addr),
34        }
35    }
36}
37
38impl fmt::Display for StdListener {
39    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40        match *self {
41            StdListener::Tcp(ref lst) => write!(f, "{}", lst.local_addr().ok().unwrap()),
42            #[cfg(all(unix))]
43            StdListener::Uds(ref lst) => write!(f, "{:?}", lst.local_addr().ok().unwrap()),
44        }
45    }
46}
47
48impl StdListener {
49    pub(crate) fn local_addr(&self) -> SocketAddr {
50        match self {
51            StdListener::Tcp(lst) => SocketAddr::Tcp(lst.local_addr().unwrap()),
52            #[cfg(all(unix))]
53            StdListener::Uds(lst) => SocketAddr::Uds(lst.local_addr().unwrap()),
54        }
55    }
56
57    pub(crate) fn into_listener(self) -> SocketListener {
58        match self {
59            StdListener::Tcp(lst) => SocketListener::Tcp(
60                mio::net::TcpListener::from_std(lst)
61                    .expect("Can not create mio::net::TcpListener"),
62            ),
63            #[cfg(all(unix))]
64            StdListener::Uds(lst) => SocketListener::Uds(
65                mio_uds::UnixListener::from_listener(lst)
66                    .expect("Can not create mio_uds::UnixListener"),
67            ),
68        }
69    }
70}
71
72#[derive(Debug)]
73pub enum StdStream {
74    Tcp(std::net::TcpStream),
75    #[cfg(all(unix))]
76    Uds(std::os::unix::net::UnixStream),
77}
78
79pub(crate) enum SocketListener {
80    Tcp(mio::net::TcpListener),
81    #[cfg(all(unix))]
82    Uds(mio_uds::UnixListener),
83}
84
85impl SocketListener {
86    pub(crate) fn accept(&self) -> io::Result<Option<(StdStream, SocketAddr)>> {
87        match *self {
88            SocketListener::Tcp(ref lst) => lst
89                .accept_std()
90                .map(|(stream, addr)| Some((StdStream::Tcp(stream), SocketAddr::Tcp(addr)))),
91            #[cfg(all(unix))]
92            SocketListener::Uds(ref lst) => lst.accept_std().map(|res| {
93                res.map(|(stream, addr)| (StdStream::Uds(stream), SocketAddr::Uds(addr)))
94            }),
95        }
96    }
97}
98
99impl mio::Evented for SocketListener {
100    fn register(
101        &self,
102        poll: &mio::Poll,
103        token: mio::Token,
104        interest: mio::Ready,
105        opts: mio::PollOpt,
106    ) -> io::Result<()> {
107        match *self {
108            SocketListener::Tcp(ref lst) => lst.register(poll, token, interest, opts),
109            #[cfg(all(unix))]
110            SocketListener::Uds(ref lst) => lst.register(poll, token, interest, opts),
111        }
112    }
113
114    fn reregister(
115        &self,
116        poll: &mio::Poll,
117        token: mio::Token,
118        interest: mio::Ready,
119        opts: mio::PollOpt,
120    ) -> io::Result<()> {
121        match *self {
122            SocketListener::Tcp(ref lst) => lst.reregister(poll, token, interest, opts),
123            #[cfg(all(unix))]
124            SocketListener::Uds(ref lst) => lst.reregister(poll, token, interest, opts),
125        }
126    }
127    fn deregister(&self, poll: &mio::Poll) -> io::Result<()> {
128        match *self {
129            SocketListener::Tcp(ref lst) => lst.deregister(poll),
130            #[cfg(all(unix))]
131            SocketListener::Uds(ref lst) => {
132                let res = lst.deregister(poll);
133
134                // cleanup file path
135                if let Ok(addr) = lst.local_addr() {
136                    if let Some(path) = addr.as_pathname() {
137                        let _ = std::fs::remove_file(path);
138                    }
139                }
140                res
141            }
142        }
143    }
144}
145
146pub trait FromStream: AsyncRead + AsyncWrite + Sized {
147    fn from_stdstream(sock: StdStream) -> io::Result<Self>;
148}
149
150impl FromStream for TcpStream {
151    fn from_stdstream(sock: StdStream) -> io::Result<Self> {
152        match sock {
153            StdStream::Tcp(stream) => TcpStream::from_std(stream),
154            #[cfg(all(unix))]
155            StdStream::Uds(_) => {
156                panic!("Should not happen, bug in server impl");
157            }
158        }
159    }
160}
161
162#[cfg(all(unix))]
163impl FromStream for requiem_rt::net::UnixStream {
164    fn from_stdstream(sock: StdStream) -> io::Result<Self> {
165        match sock {
166            StdStream::Tcp(_) => panic!("Should not happen, bug in server impl"),
167            StdStream::Uds(stream) => requiem_rt::net::UnixStream::from_std(stream),
168        }
169    }
170}