1use std::fmt::Arguments;
4use std::io::{self, Read, Write};
5
6pub trait Stream: Read + Write {}
10impl<S> Stream for S where S: Read + Write {}
11
12pub struct ReadWritePair<R, W>(pub R, pub W)
17where
18 R: Read,
19 W: Write;
20
21impl<R, W> Read for ReadWritePair<R, W>
22where
23 R: Read,
24 W: Write,
25{
26 #[inline(always)]
27 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
28 self.0.read(buf)
29 }
30 #[inline(always)]
31 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
32 self.0.read_to_end(buf)
33 }
34 #[inline(always)]
35 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
36 self.0.read_to_string(buf)
37 }
38 #[inline(always)]
39 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
40 self.0.read_exact(buf)
41 }
42}
43
44impl<R, W> Write for ReadWritePair<R, W>
45where
46 R: Read,
47 W: Write,
48{
49 #[inline(always)]
50 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
51 self.1.write(buf)
52 }
53 #[inline(always)]
54 fn flush(&mut self) -> io::Result<()> {
55 self.1.flush()
56 }
57 #[inline(always)]
58 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
59 self.1.write_all(buf)
60 }
61 #[inline(always)]
62 fn write_fmt(&mut self, fmt: Arguments) -> io::Result<()> {
63 self.1.write_fmt(fmt)
64 }
65}
66
67#[cfg(feature = "async")]
69pub mod r#async {
70 pub use super::ReadWritePair;
71 use futures::Poll;
72 use std::io::{self, Read, Write};
73 pub use tokio_io::io::{ReadHalf, WriteHalf};
74 pub use tokio_io::{AsyncRead, AsyncWrite};
75 pub use tokio_tcp::TcpStream;
76
77 pub trait Stream: AsyncRead + AsyncWrite {}
81 impl<S> Stream for S where S: AsyncRead + AsyncWrite {}
82
83 impl<R, W> AsyncRead for ReadWritePair<R, W>
84 where
85 R: AsyncRead,
86 W: Write,
87 {
88 }
89
90 impl<R, W> AsyncWrite for ReadWritePair<R, W>
91 where
92 W: AsyncWrite,
93 R: Read,
94 {
95 fn shutdown(&mut self) -> Poll<(), io::Error> {
96 self.1.shutdown()
97 }
98 }
99}
100
101#[cfg(feature = "sync")]
103pub mod sync {
104 pub use super::ReadWritePair;
105 #[cfg(feature = "sync-ssl")]
106 pub use native_tls::TlsStream;
107 use std::io::{self, Read, Write};
108 pub use std::net::Shutdown;
109 pub use std::net::TcpStream;
110 use std::ops::Deref;
111
112 pub use super::Stream;
113
114 pub trait NetworkStream: Read + Write + AsTcpStream {}
118
119 impl<S> NetworkStream for S where S: Read + Write + AsTcpStream {}
120
121 pub trait Splittable {
127 type Reader: Read;
129 type Writer: Write;
131
132 fn split(self) -> io::Result<(Self::Reader, Self::Writer)>;
134 }
135
136 impl<R, W> Splittable for ReadWritePair<R, W>
137 where
138 R: Read,
139 W: Write,
140 {
141 type Reader = R;
142 type Writer = W;
143
144 fn split(self) -> io::Result<(R, W)> {
145 Ok((self.0, self.1))
146 }
147 }
148
149 impl Splittable for TcpStream {
150 type Reader = TcpStream;
151 type Writer = TcpStream;
152
153 fn split(self) -> io::Result<(TcpStream, TcpStream)> {
154 self.try_clone().map(|s| (s, self))
155 }
156 }
157
158 pub trait AsTcpStream {
161 fn as_tcp(&self) -> &TcpStream;
163 }
164
165 impl AsTcpStream for TcpStream {
166 fn as_tcp(&self) -> &TcpStream {
167 self
168 }
169 }
170
171 #[cfg(feature = "sync-ssl")]
172 impl AsTcpStream for TlsStream<TcpStream> {
173 fn as_tcp(&self) -> &TcpStream {
174 self.get_ref()
175 }
176 }
177
178 impl<T> AsTcpStream for Box<T>
179 where
180 T: AsTcpStream + ?Sized,
181 {
182 fn as_tcp(&self) -> &TcpStream {
183 self.deref().as_tcp()
184 }
185 }
186}