• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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