1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use std::future::Future; 15 use std::io; 16 use std::io::IoSlice; 17 use std::pin::Pin; 18 use std::task::{Context, Poll}; 19 20 use crate::io::AsyncWrite; 21 22 macro_rules! take_writer { 23 ($self: expr) => { 24 match $self.writer.take() { 25 Some(writer) => writer, 26 None => panic!("write: poll after finished"), 27 } 28 }; 29 } 30 31 /// A future for writing some of the buffer to the io 32 /// 33 /// Returned by [`crate::io::AsyncWriteExt::write`] 34 pub struct WriteTask<'a, W: ?Sized> { 35 writer: Option<&'a mut W>, 36 buf: &'a [u8], 37 } 38 39 impl<'a, W: ?Sized> WriteTask<'a, W> 40 where 41 W: AsyncWrite + Unpin, 42 { 43 #[inline(always)] new(writer: &'a mut W, buf: &'a [u8]) -> WriteTask<'a, W>44 pub(crate) fn new(writer: &'a mut W, buf: &'a [u8]) -> WriteTask<'a, W> { 45 WriteTask { 46 writer: Some(writer), 47 buf, 48 } 49 } 50 } 51 52 impl<'a, W> Future for WriteTask<'a, W> 53 where 54 W: AsyncWrite + Unpin, 55 { 56 type Output = io::Result<usize>; 57 poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>58 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 59 let mut writer = take_writer!(self); 60 61 match Pin::new(&mut writer).poll_write(cx, self.buf) { 62 Poll::Pending => { 63 self.writer = Some(writer); 64 Poll::Pending 65 } 66 x => x, 67 } 68 } 69 } 70 71 /// A future for writing data inside a vector to the io 72 /// 73 /// Returned by [`crate::io::AsyncWriteExt::write_vectored`] 74 pub struct WriteVectoredTask<'a, 'b, W: ?Sized> { 75 writer: Option<&'a mut W>, 76 bufs: &'a [IoSlice<'b>], 77 } 78 79 impl<'a, 'b, W: ?Sized> WriteVectoredTask<'a, 'b, W> 80 where 81 W: AsyncWrite + Unpin, 82 { 83 #[inline(always)] new(writer: &'a mut W, bufs: &'a [IoSlice<'b>]) -> WriteVectoredTask<'a, 'b, W>84 pub(crate) fn new(writer: &'a mut W, bufs: &'a [IoSlice<'b>]) -> WriteVectoredTask<'a, 'b, W> { 85 WriteVectoredTask { 86 writer: Some(writer), 87 bufs, 88 } 89 } 90 } 91 92 impl<'a, 'b, W: ?Sized> Future for WriteVectoredTask<'a, 'b, W> 93 where 94 W: AsyncWrite + Unpin, 95 { 96 type Output = io::Result<usize>; 97 poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>98 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 99 let mut writer = take_writer!(self); 100 101 match Pin::new(&mut writer).poll_write_vectored(cx, self.bufs) { 102 Poll::Pending => { 103 self.writer = Some(writer); 104 Poll::Pending 105 } 106 x => x, 107 } 108 } 109 } 110 111 /// A future for writing every data inside a buffer to the io 112 /// 113 /// Returned by [`crate::io::AsyncWriteExt::write_all`] 114 pub struct WriteAllTask<'a, W: ?Sized> { 115 writer: Option<&'a mut W>, 116 buf: &'a [u8], 117 w_len: usize, 118 } 119 120 impl<'a, W: ?Sized> WriteAllTask<'a, W> 121 where 122 W: AsyncWrite + Unpin, 123 { 124 #[inline(always)] new(writer: &'a mut W, buf: &'a [u8]) -> WriteAllTask<'a, W>125 pub(crate) fn new(writer: &'a mut W, buf: &'a [u8]) -> WriteAllTask<'a, W> { 126 WriteAllTask { 127 writer: Some(writer), 128 buf, 129 w_len: 0, 130 } 131 } 132 } 133 134 impl<'a, W> Future for WriteAllTask<'a, W> 135 where 136 W: AsyncWrite + Unpin, 137 { 138 type Output = io::Result<()>; 139 poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>140 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 141 let mut writer = take_writer!(self); 142 while self.w_len < self.buf.len() { 143 match Pin::new(&mut writer).poll_write(cx, &self.buf[self.w_len..]) { 144 Poll::Ready(Ok(0)) => return Poll::Ready(Err(io::ErrorKind::WriteZero.into())), 145 Poll::Ready(Ok(n)) => self.w_len += n, 146 Poll::Ready(Err(e)) => return Poll::Ready(Err(e)), 147 Poll::Pending => { 148 self.writer = Some(writer); 149 return Poll::Pending; 150 } 151 } 152 } 153 Poll::Ready(Ok(())) 154 } 155 } 156 157 pub struct FlushTask<'a, W: ?Sized> { 158 writer: &'a mut W, 159 } 160 161 impl<'a, W: ?Sized> FlushTask<'a, W> 162 where 163 W: AsyncWrite + Unpin, 164 { 165 #[inline(always)] new(writer: &'a mut W) -> FlushTask<'a, W>166 pub(crate) fn new(writer: &'a mut W) -> FlushTask<'a, W> { 167 FlushTask { writer } 168 } 169 } 170 171 impl<'a, W> Future for FlushTask<'a, W> 172 where 173 W: AsyncWrite + Unpin + ?Sized, 174 { 175 type Output = io::Result<()>; 176 poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>177 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 178 let me = self.get_mut(); 179 Pin::new(&mut me.writer).poll_flush(cx) 180 } 181 } 182 pub struct ShutdownTask<'a, W: ?Sized> { 183 writer: &'a mut W, 184 } 185 186 impl<'a, W: ?Sized> ShutdownTask<'a, W> 187 where 188 W: AsyncWrite + Unpin, 189 { 190 #[inline(always)] new(writer: &'a mut W) -> ShutdownTask<'a, W>191 pub(crate) fn new(writer: &'a mut W) -> ShutdownTask<'a, W> { 192 ShutdownTask { writer } 193 } 194 } 195 196 impl<'a, W> Future for ShutdownTask<'a, W> 197 where 198 W: AsyncWrite + Unpin + ?Sized, 199 { 200 type Output = io::Result<()>; 201 poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>202 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 203 let me = self.get_mut(); 204 Pin::new(&mut me.writer).poll_shutdown(cx) 205 } 206 } 207