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 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}