@@ -43,6 +43,7 @@ use crate::task::{Context, Poll};
43
43
/// #
44
44
/// # Ok(()) }) }
45
45
/// ```
46
+ #[ cfg( any( feature = "docs" , not( feature = "unstable" ) ) ) ]
46
47
pub async fn copy < R , W > ( reader : & mut R , writer : & mut W ) -> io:: Result < u64 >
47
48
where
48
49
R : Read + Unpin + ?Sized ,
91
92
} ;
92
93
future. await
93
94
}
95
+
96
+ /// Copies the entire contents of a reader into a writer.
97
+ ///
98
+ /// This function will continuously read data from `reader` and then
99
+ /// write it into `writer` in a streaming fashion until `reader`
100
+ /// returns EOF.
101
+ ///
102
+ /// On success, the total number of bytes that were copied from
103
+ /// `reader` to `writer` is returned.
104
+ ///
105
+ /// If you’re wanting to copy the contents of one file to another and you’re
106
+ /// working with filesystem paths, see the [`fs::copy`] function.
107
+ ///
108
+ /// This function is an async version of [`std::io::copy`].
109
+ ///
110
+ /// [`std::io::copy`]: https://doc.rust-lang.org/std/io/fn.copy.html
111
+ /// [`fs::copy`]: ../fs/fn.copy.html
112
+ ///
113
+ /// # Errors
114
+ ///
115
+ /// This function will return an error immediately if any call to `read` or
116
+ /// `write` returns an error. All instances of `ErrorKind::Interrupted` are
117
+ /// handled by this function and the underlying operation is retried.
118
+ ///
119
+ /// # Examples
120
+ ///
121
+ /// ```
122
+ /// # fn main() -> std::io::Result<()> { async_std::task::block_on(async {
123
+ /// #
124
+ /// use async_std::io;
125
+ ///
126
+ /// let mut reader: &[u8] = b"hello";
127
+ /// let mut writer = io::stdout();
128
+ ///
129
+ /// io::copy(&mut reader, &mut writer).await?;
130
+ /// #
131
+ /// # Ok(()) }) }
132
+ /// ```
133
+ #[ cfg( all( feature = "unstable" , not( feature = "docs" ) ) ) ]
134
+ pub async fn copy < R , W > ( reader : R , writer : W ) -> io:: Result < u64 >
135
+ where
136
+ R : Read + Unpin ,
137
+ W : Write + Unpin ,
138
+ {
139
+ pin_project ! {
140
+ struct CopyFuture <R , W > {
141
+ #[ pin]
142
+ reader: R ,
143
+ #[ pin]
144
+ writer: W ,
145
+ amt: u64 ,
146
+ }
147
+ }
148
+
149
+ impl < R , W > Future for CopyFuture < R , W >
150
+ where
151
+ R : BufRead ,
152
+ W : Write + Unpin ,
153
+ {
154
+ type Output = io:: Result < u64 > ;
155
+
156
+ fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
157
+ let mut this = self . project ( ) ;
158
+ loop {
159
+ let buffer = futures_core:: ready!( this. reader. as_mut( ) . poll_fill_buf( cx) ) ?;
160
+ if buffer. is_empty ( ) {
161
+ futures_core:: ready!( this. writer. as_mut( ) . poll_flush( cx) ) ?;
162
+ return Poll :: Ready ( Ok ( * this. amt ) ) ;
163
+ }
164
+
165
+ let i = futures_core:: ready!( this. writer. as_mut( ) . poll_write( cx, buffer) ) ?;
166
+ if i == 0 {
167
+ return Poll :: Ready ( Err ( io:: ErrorKind :: WriteZero . into ( ) ) ) ;
168
+ }
169
+ * this. amt += i as u64 ;
170
+ this. reader . as_mut ( ) . consume ( i) ;
171
+ }
172
+ }
173
+ }
174
+
175
+ let future = CopyFuture {
176
+ reader : BufReader :: new ( reader) ,
177
+ writer,
178
+ amt : 0 ,
179
+ } ;
180
+ future. await
181
+ }
0 commit comments