1 //! `UnixStream` split support.
2 //!
3 //! A `UnixStream` can be split into a read half and a write half with
4 //! `UnixStream::split`. The read half implements `AsyncRead` while the write
5 //! half implements `AsyncWrite`.
6 //!
7 //! Compared to the generic split of `AsyncRead + AsyncWrite`, this specialized
8 //! split has no associated overhead and enforces all invariants at the type
9 //! level.
10
11 use crate::io::{AsyncRead, AsyncWrite, ReadBuf};
12 use crate::net::UnixStream;
13
14 use std::io;
15 use std::net::Shutdown;
16 use std::pin::Pin;
17 use std::task::{Context, Poll};
18
19 /// Borrowed read half of a [`UnixStream`], created by [`split`].
20 ///
21 /// Reading from a `ReadHalf` is usually done using the convenience methods found on the
22 /// [`AsyncReadExt`] trait.
23 ///
24 /// [`UnixStream`]: UnixStream
25 /// [`split`]: UnixStream::split()
26 /// [`AsyncReadExt`]: trait@crate::io::AsyncReadExt
27 #[derive(Debug)]
28 pub struct ReadHalf<'a>(&'a UnixStream);
29
30 /// Borrowed write half of a [`UnixStream`], created by [`split`].
31 ///
32 /// Note that in the [`AsyncWrite`] implemenation of this type, [`poll_shutdown`] will
33 /// shut down the UnixStream stream in the write direction.
34 ///
35 /// Writing to an `WriteHalf` is usually done using the convenience methods found
36 /// on the [`AsyncWriteExt`] trait.
37 ///
38 /// [`UnixStream`]: UnixStream
39 /// [`split`]: UnixStream::split()
40 /// [`AsyncWrite`]: trait@crate::io::AsyncWrite
41 /// [`poll_shutdown`]: fn@crate::io::AsyncWrite::poll_shutdown
42 /// [`AsyncWriteExt`]: trait@crate::io::AsyncWriteExt
43 #[derive(Debug)]
44 pub struct WriteHalf<'a>(&'a UnixStream);
45
split(stream: &mut UnixStream) -> (ReadHalf<'_>, WriteHalf<'_>)46 pub(crate) fn split(stream: &mut UnixStream) -> (ReadHalf<'_>, WriteHalf<'_>) {
47 (ReadHalf(stream), WriteHalf(stream))
48 }
49
50 impl AsyncRead for ReadHalf<'_> {
poll_read( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<io::Result<()>>51 fn poll_read(
52 self: Pin<&mut Self>,
53 cx: &mut Context<'_>,
54 buf: &mut ReadBuf<'_>,
55 ) -> Poll<io::Result<()>> {
56 self.0.poll_read_priv(cx, buf)
57 }
58 }
59
60 impl AsyncWrite for WriteHalf<'_> {
poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], ) -> Poll<io::Result<usize>>61 fn poll_write(
62 self: Pin<&mut Self>,
63 cx: &mut Context<'_>,
64 buf: &[u8],
65 ) -> Poll<io::Result<usize>> {
66 self.0.poll_write_priv(cx, buf)
67 }
68
poll_write_vectored( self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[io::IoSlice<'_>], ) -> Poll<io::Result<usize>>69 fn poll_write_vectored(
70 self: Pin<&mut Self>,
71 cx: &mut Context<'_>,
72 bufs: &[io::IoSlice<'_>],
73 ) -> Poll<io::Result<usize>> {
74 self.0.poll_write_vectored_priv(cx, bufs)
75 }
76
is_write_vectored(&self) -> bool77 fn is_write_vectored(&self) -> bool {
78 self.0.is_write_vectored()
79 }
80
poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>>81 fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
82 Poll::Ready(Ok(()))
83 }
84
poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>>85 fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
86 self.0.shutdown_std(Shutdown::Write).into()
87 }
88 }
89
90 impl AsRef<UnixStream> for ReadHalf<'_> {
as_ref(&self) -> &UnixStream91 fn as_ref(&self) -> &UnixStream {
92 self.0
93 }
94 }
95
96 impl AsRef<UnixStream> for WriteHalf<'_> {
as_ref(&self) -> &UnixStream97 fn as_ref(&self) -> &UnixStream {
98 self.0
99 }
100 }
101