broker_tokio/io/util/async_write_ext.rs
1use crate::io::util::flush::{flush, Flush};
2use crate::io::util::shutdown::{shutdown, Shutdown};
3use crate::io::util::write::{write, Write};
4use crate::io::util::write_all::{write_all, WriteAll};
5use crate::io::util::write_buf::{write_buf, WriteBuf};
6use crate::io::util::write_int::{WriteI128, WriteI16, WriteI32, WriteI64, WriteI8};
7use crate::io::util::write_int::{WriteU128, WriteU16, WriteU32, WriteU64, WriteU8};
8use crate::io::AsyncWrite;
9
10use bytes::Buf;
11
12cfg_io_util! {
13 /// Define numeric writer
14 macro_rules! write_impl {
15 (
16 $(
17 $(#[$outer:meta])*
18 fn $name:ident(&mut self, n: $ty:ty) -> $($fut:ident)*;
19 )*
20 ) => {
21 $(
22 $(#[$outer])*
23 fn $name<'a>(&'a mut self, n: $ty) -> $($fut)*<&'a mut Self> where Self: Unpin {
24 $($fut)*::new(self, n)
25 }
26 )*
27 }
28 }
29
30 /// Write bytes to a sink.
31 ///
32 /// Implemented as an extention trait, adding utility methods to all
33 /// [`AsyncWrite`] types. Callers will tend to import this trait instead of
34 /// [`AsyncWrite`].
35 ///
36 /// As a convenience, this trait may be imported using the [`prelude`]:
37 ///
38 /// ```no_run
39 /// use tokio::prelude::*;
40 /// use tokio::fs::File;
41 ///
42 /// #[tokio::main]
43 /// async fn main() -> io::Result<()> {
44 /// let data = b"some bytes";
45 ///
46 /// let mut pos = 0;
47 /// let mut buffer = File::create("foo.txt").await?;
48 ///
49 /// while pos < data.len() {
50 /// let bytes_written = buffer.write(&data[pos..]).await?;
51 /// pos += bytes_written;
52 /// }
53 ///
54 /// Ok(())
55 /// }
56 /// ```
57 ///
58 /// See [module][crate::io] documentation for more details.
59 ///
60 /// [`AsyncWrite`]: AsyncWrite
61 /// [`prelude`]: crate::prelude
62 pub trait AsyncWriteExt: AsyncWrite {
63 /// Write a buffer into this writer, returning how many bytes were
64 /// written.
65 ///
66 /// Equivalent to:
67 ///
68 /// ```ignore
69 /// async fn write(&mut self, buf: &[u8]) -> io::Result<usize>;
70 /// ```
71 ///
72 /// This function will attempt to write the entire contents of `buf`, but
73 /// the entire write may not succeed, or the write may also generate an
74 /// error. A call to `write` represents *at most one* attempt to write to
75 /// any wrapped object.
76 ///
77 /// # Return
78 ///
79 /// If the return value is `Ok(n)` then it must be guaranteed that `n <=
80 /// buf.len()`. A return value of `0` typically means that the
81 /// underlying object is no longer able to accept bytes and will likely
82 /// not be able to in the future as well, or that the buffer provided is
83 /// empty.
84 ///
85 /// # Errors
86 ///
87 /// Each call to `write` may generate an I/O error indicating that the
88 /// operation could not be completed. If an error is returned then no bytes
89 /// in the buffer were written to this writer.
90 ///
91 /// It is **not** considered an error if the entire buffer could not be
92 /// written to this writer.
93 ///
94 /// # Examples
95 ///
96 /// ```no_run
97 /// use tokio::io::{self, AsyncWriteExt};
98 /// use tokio::fs::File;
99 ///
100 /// #[tokio::main]
101 /// async fn main() -> io::Result<()> {
102 /// let mut file = File::create("foo.txt").await?;
103 ///
104 /// // Writes some prefix of the byte string, not necessarily all of it.
105 /// file.write(b"some bytes").await?;
106 /// Ok(())
107 /// }
108 /// ```
109 fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
110 where
111 Self: Unpin,
112 {
113 write(self, src)
114 }
115
116 /// Write a buffer into this writer, advancing the buffer's internal
117 /// cursor.
118 ///
119 /// Equivalent to:
120 ///
121 /// ```ignore
122 /// async fn write_buf<B: Buf>(&mut self, buf: &mut B) -> io::Result<usize>;
123 /// ```
124 ///
125 /// This function will attempt to write the entire contents of `buf`, but
126 /// the entire write may not succeed, or the write may also generate an
127 /// error. After the operation completes, the buffer's
128 /// internal cursor is advanced by the number of bytes written. A
129 /// subsequent call to `write_buf` using the **same** `buf` value will
130 /// resume from the point that the first call to `write_buf` completed.
131 /// A call to `write` represents *at most one* attempt to write to any
132 /// wrapped object.
133 ///
134 /// # Return
135 ///
136 /// If the return value is `Ok(n)` then it must be guaranteed that `n <=
137 /// buf.len()`. A return value of `0` typically means that the
138 /// underlying object is no longer able to accept bytes and will likely
139 /// not be able to in the future as well, or that the buffer provided is
140 /// empty.
141 ///
142 /// # Errors
143 ///
144 /// Each call to `write` may generate an I/O error indicating that the
145 /// operation could not be completed. If an error is returned then no bytes
146 /// in the buffer were written to this writer.
147 ///
148 /// It is **not** considered an error if the entire buffer could not be
149 /// written to this writer.
150 ///
151 /// # Examples
152 ///
153 /// [`File`] implements `Read` and [`Cursor<&[u8]>`] implements [`Buf`]:
154 ///
155 /// [`File`]: crate::fs::File
156 /// [`Buf`]: bytes::Buf
157 ///
158 /// ```no_run
159 /// use tokio::io::{self, AsyncWriteExt};
160 /// use tokio::fs::File;
161 ///
162 /// use bytes::Buf;
163 /// use std::io::Cursor;
164 ///
165 /// #[tokio::main]
166 /// async fn main() -> io::Result<()> {
167 /// let mut file = File::create("foo.txt").await?;
168 /// let mut buffer = Cursor::new(b"data to write");
169 ///
170 /// // Loop until the entire contents of the buffer are written to
171 /// // the file.
172 /// while buffer.has_remaining() {
173 /// // Writes some prefix of the byte string, not necessarily
174 /// // all of it.
175 /// file.write_buf(&mut buffer).await?;
176 /// }
177 ///
178 /// Ok(())
179 /// }
180 /// ```
181 fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
182 where
183 Self: Sized,
184 B: Buf,
185 {
186 write_buf(self, src)
187 }
188
189 /// Attempts to write an entire buffer into this writer.
190 ///
191 /// Equivalent to:
192 ///
193 /// ```ignore
194 /// async fn write_all(&mut self, buf: &[u8]) -> io::Result<()>;
195 /// ```
196 ///
197 /// This method will continuously call [`write`] until there is no more data
198 /// to be written. This method will not return until the entire buffer
199 /// has been successfully written or such an error occurs. The first
200 /// error generated from this method will be returned.
201 ///
202 /// # Errors
203 ///
204 /// This function will return the first error that [`write`] returns.
205 ///
206 /// # Examples
207 ///
208 /// ```no_run
209 /// use tokio::io::{self, AsyncWriteExt};
210 /// use tokio::fs::File;
211 ///
212 /// #[tokio::main]
213 /// async fn main() -> io::Result<()> {
214 /// let mut buffer = File::create("foo.txt").await?;
215 ///
216 /// buffer.write_all(b"some bytes").await?;
217 /// Ok(())
218 /// }
219 /// ```
220 ///
221 /// [`write`]: AsyncWriteExt::write
222 fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
223 where
224 Self: Unpin,
225 {
226 write_all(self, src)
227 }
228
229 write_impl! {
230 /// Writes an unsigned 8-bit integer to the underlying writer.
231 ///
232 /// Equivalent to:
233 ///
234 /// ```ignore
235 /// async fn write_u8(&mut self, n: u8) -> io::Result<()>;
236 /// ```
237 ///
238 /// It is recommended to use a buffered writer to avoid excessive
239 /// syscalls.
240 ///
241 /// # Errors
242 ///
243 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
244 ///
245 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
246 ///
247 /// # Examples
248 ///
249 /// Write unsigned 8 bit integers to a `AsyncWrite`:
250 ///
251 /// ```rust
252 /// use tokio::io::{self, AsyncWriteExt};
253 ///
254 /// #[tokio::main]
255 /// async fn main() -> io::Result<()> {
256 /// let mut writer = Vec::new();
257 ///
258 /// writer.write_u8(2).await?;
259 /// writer.write_u8(5).await?;
260 ///
261 /// assert_eq!(writer, b"\x02\x05");
262 /// Ok(())
263 /// }
264 /// ```
265 fn write_u8(&mut self, n: u8) -> WriteU8;
266
267 /// Writes an unsigned 8-bit integer to the underlying writer.
268 ///
269 /// Equivalent to:
270 ///
271 /// ```ignore
272 /// async fn write_i8(&mut self, n: i8) -> io::Result<()>;
273 /// ```
274 ///
275 /// It is recommended to use a buffered writer to avoid excessive
276 /// syscalls.
277 ///
278 /// # Errors
279 ///
280 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
281 ///
282 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
283 ///
284 /// # Examples
285 ///
286 /// Write unsigned 8 bit integers to a `AsyncWrite`:
287 ///
288 /// ```rust
289 /// use tokio::io::{self, AsyncWriteExt};
290 ///
291 /// #[tokio::main]
292 /// async fn main() -> io::Result<()> {
293 /// let mut writer = Vec::new();
294 ///
295 /// writer.write_u8(2).await?;
296 /// writer.write_u8(5).await?;
297 ///
298 /// assert_eq!(writer, b"\x02\x05");
299 /// Ok(())
300 /// }
301 /// ```
302 fn write_i8(&mut self, n: i8) -> WriteI8;
303
304 /// Writes an unsigned 16-bit integer in big-endian order to the
305 /// underlying writer.
306 ///
307 /// Equivalent to:
308 ///
309 /// ```ignore
310 /// async fn write_u16(&mut self, n: u16) -> io::Result<()>;
311 /// ```
312 ///
313 /// It is recommended to use a buffered writer to avoid excessive
314 /// syscalls.
315 ///
316 /// # Errors
317 ///
318 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
319 ///
320 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
321 ///
322 /// # Examples
323 ///
324 /// Write unsigned 16-bit integers to a `AsyncWrite`:
325 ///
326 /// ```rust
327 /// use tokio::io::{self, AsyncWriteExt};
328 ///
329 /// #[tokio::main]
330 /// async fn main() -> io::Result<()> {
331 /// let mut writer = Vec::new();
332 ///
333 /// writer.write_u16(517).await?;
334 /// writer.write_u16(768).await?;
335 ///
336 /// assert_eq!(writer, b"\x02\x05\x03\x00");
337 /// Ok(())
338 /// }
339 /// ```
340 fn write_u16(&mut self, n: u16) -> WriteU16;
341
342 /// Writes a signed 16-bit integer in big-endian order to the
343 /// underlying writer.
344 ///
345 /// Equivalent to:
346 ///
347 /// ```ignore
348 /// async fn write_i16(&mut self, n: i16) -> io::Result<()>;
349 /// ```
350 ///
351 /// It is recommended to use a buffered writer to avoid excessive
352 /// syscalls.
353 ///
354 /// # Errors
355 ///
356 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
357 ///
358 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
359 ///
360 /// # Examples
361 ///
362 /// Write signed 16-bit integers to a `AsyncWrite`:
363 ///
364 /// ```rust
365 /// use tokio::io::{self, AsyncWriteExt};
366 ///
367 /// #[tokio::main]
368 /// async fn main() -> io::Result<()> {
369 /// let mut writer = Vec::new();
370 ///
371 /// writer.write_i16(193).await?;
372 /// writer.write_i16(-132).await?;
373 ///
374 /// assert_eq!(writer, b"\x00\xc1\xff\x7c");
375 /// Ok(())
376 /// }
377 /// ```
378 fn write_i16(&mut self, n: i16) -> WriteI16;
379
380 /// Writes an unsigned 32-bit integer in big-endian order to the
381 /// underlying writer.
382 ///
383 /// Equivalent to:
384 ///
385 /// ```ignore
386 /// async fn write_u32(&mut self, n: u32) -> io::Result<()>;
387 /// ```
388 ///
389 /// It is recommended to use a buffered writer to avoid excessive
390 /// syscalls.
391 ///
392 /// # Errors
393 ///
394 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
395 ///
396 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
397 ///
398 /// # Examples
399 ///
400 /// Write unsigned 32-bit integers to a `AsyncWrite`:
401 ///
402 /// ```rust
403 /// use tokio::io::{self, AsyncWriteExt};
404 ///
405 /// #[tokio::main]
406 /// async fn main() -> io::Result<()> {
407 /// let mut writer = Vec::new();
408 ///
409 /// writer.write_u32(267).await?;
410 /// writer.write_u32(1205419366).await?;
411 ///
412 /// assert_eq!(writer, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66");
413 /// Ok(())
414 /// }
415 /// ```
416 fn write_u32(&mut self, n: u32) -> WriteU32;
417
418 /// Writes a signed 32-bit integer in big-endian order to the
419 /// underlying writer.
420 ///
421 /// Equivalent to:
422 ///
423 /// ```ignore
424 /// async fn write_i32(&mut self, n: i32) -> io::Result<()>;
425 /// ```
426 ///
427 /// It is recommended to use a buffered writer to avoid excessive
428 /// syscalls.
429 ///
430 /// # Errors
431 ///
432 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
433 ///
434 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
435 ///
436 /// # Examples
437 ///
438 /// Write signed 32-bit integers to a `AsyncWrite`:
439 ///
440 /// ```rust
441 /// use tokio::io::{self, AsyncWriteExt};
442 ///
443 /// #[tokio::main]
444 /// async fn main() -> io::Result<()> {
445 /// let mut writer = Vec::new();
446 ///
447 /// writer.write_i32(267).await?;
448 /// writer.write_i32(1205419366).await?;
449 ///
450 /// assert_eq!(writer, b"\x00\x00\x01\x0b\x47\xd9\x3d\x66");
451 /// Ok(())
452 /// }
453 /// ```
454 fn write_i32(&mut self, n: i32) -> WriteI32;
455
456 /// Writes an unsigned 64-bit integer in big-endian order to the
457 /// underlying writer.
458 ///
459 /// Equivalent to:
460 ///
461 /// ```ignore
462 /// async fn write_u64(&mut self, n: u64) -> io::Result<()>;
463 /// ```
464 ///
465 /// It is recommended to use a buffered writer to avoid excessive
466 /// syscalls.
467 ///
468 /// # Errors
469 ///
470 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
471 ///
472 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
473 ///
474 /// # Examples
475 ///
476 /// Write unsigned 64-bit integers to a `AsyncWrite`:
477 ///
478 /// ```rust
479 /// use tokio::io::{self, AsyncWriteExt};
480 ///
481 /// #[tokio::main]
482 /// async fn main() -> io::Result<()> {
483 /// let mut writer = Vec::new();
484 ///
485 /// writer.write_u64(918733457491587).await?;
486 /// writer.write_u64(143).await?;
487 ///
488 /// assert_eq!(writer, b"\x00\x03\x43\x95\x4d\x60\x86\x83\x00\x00\x00\x00\x00\x00\x00\x8f");
489 /// Ok(())
490 /// }
491 /// ```
492 fn write_u64(&mut self, n: u64) -> WriteU64;
493
494 /// Writes an signed 64-bit integer in big-endian order to the
495 /// underlying writer.
496 ///
497 /// Equivalent to:
498 ///
499 /// ```ignore
500 /// async fn write_i64(&mut self, n: i64) -> io::Result<()>;
501 /// ```
502 ///
503 /// It is recommended to use a buffered writer to avoid excessive
504 /// syscalls.
505 ///
506 /// # Errors
507 ///
508 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
509 ///
510 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
511 ///
512 /// # Examples
513 ///
514 /// Write signed 64-bit integers to a `AsyncWrite`:
515 ///
516 /// ```rust
517 /// use tokio::io::{self, AsyncWriteExt};
518 ///
519 /// #[tokio::main]
520 /// async fn main() -> io::Result<()> {
521 /// let mut writer = Vec::new();
522 ///
523 /// writer.write_i64(i64::min_value()).await?;
524 /// writer.write_i64(i64::max_value()).await?;
525 ///
526 /// assert_eq!(writer, b"\x80\x00\x00\x00\x00\x00\x00\x00\x7f\xff\xff\xff\xff\xff\xff\xff");
527 /// Ok(())
528 /// }
529 /// ```
530 fn write_i64(&mut self, n: i64) -> WriteI64;
531
532 /// Writes an unsigned 128-bit integer in big-endian order to the
533 /// underlying writer.
534 ///
535 /// Equivalent to:
536 ///
537 /// ```ignore
538 /// async fn write_u128(&mut self, n: u128) -> io::Result<()>;
539 /// ```
540 ///
541 /// It is recommended to use a buffered writer to avoid excessive
542 /// syscalls.
543 ///
544 /// # Errors
545 ///
546 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
547 ///
548 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
549 ///
550 /// # Examples
551 ///
552 /// Write unsigned 128-bit integers to a `AsyncWrite`:
553 ///
554 /// ```rust
555 /// use tokio::io::{self, AsyncWriteExt};
556 ///
557 /// #[tokio::main]
558 /// async fn main() -> io::Result<()> {
559 /// let mut writer = Vec::new();
560 ///
561 /// writer.write_u128(16947640962301618749969007319746179).await?;
562 ///
563 /// assert_eq!(writer, vec![
564 /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83,
565 /// 0x00, 0x03, 0x43, 0x95, 0x4d, 0x60, 0x86, 0x83
566 /// ]);
567 /// Ok(())
568 /// }
569 /// ```
570 fn write_u128(&mut self, n: u128) -> WriteU128;
571
572 /// Writes an signed 128-bit integer in big-endian order to the
573 /// underlying writer.
574 ///
575 /// Equivalent to:
576 ///
577 /// ```ignore
578 /// async fn write_i128(&mut self, n: i128) -> io::Result<()>;
579 /// ```
580 ///
581 /// It is recommended to use a buffered writer to avoid excessive
582 /// syscalls.
583 ///
584 /// # Errors
585 ///
586 /// This method returns the same errors as [`AsyncWriteExt::write_all`].
587 ///
588 /// [`AsyncWriteExt::write_all`]: AsyncWriteExt::write_all
589 ///
590 /// # Examples
591 ///
592 /// Write signed 128-bit integers to a `AsyncWrite`:
593 ///
594 /// ```rust
595 /// use tokio::io::{self, AsyncWriteExt};
596 ///
597 /// #[tokio::main]
598 /// async fn main() -> io::Result<()> {
599 /// let mut writer = Vec::new();
600 ///
601 /// writer.write_i128(i128::min_value()).await?;
602 ///
603 /// assert_eq!(writer, vec![
604 /// 0x80, 0, 0, 0, 0, 0, 0, 0,
605 /// 0, 0, 0, 0, 0, 0, 0, 0
606 /// ]);
607 /// Ok(())
608 /// }
609 /// ```
610 fn write_i128(&mut self, n: i128) -> WriteI128;
611 }
612
613 /// Flush this output stream, ensuring that all intermediately buffered
614 /// contents reach their destination.
615 ///
616 /// Equivalent to:
617 ///
618 /// ```ignore
619 /// async fn flush(&mut self) -> io::Result<()>;
620 /// ```
621 ///
622 /// # Errors
623 ///
624 /// It is considered an error if not all bytes could be written due to
625 /// I/O errors or EOF being reached.
626 ///
627 /// # Examples
628 ///
629 /// ```no_run
630 /// use tokio::io::{self, BufWriter, AsyncWriteExt};
631 /// use tokio::fs::File;
632 ///
633 /// #[tokio::main]
634 /// async fn main() -> io::Result<()> {
635 /// let f = File::create("foo.txt").await?;
636 /// let mut buffer = BufWriter::new(f);
637 ///
638 /// buffer.write_all(b"some bytes").await?;
639 /// buffer.flush().await?;
640 /// Ok(())
641 /// }
642 /// ```
643 fn flush(&mut self) -> Flush<'_, Self>
644 where
645 Self: Unpin,
646 {
647 flush(self)
648 }
649
650 /// Shuts down the output stream, ensuring that the value can be dropped
651 /// cleanly.
652 ///
653 /// Equivalent to:
654 ///
655 /// ```ignore
656 /// async fn shutdown(&mut self) -> io::Result<()>;
657 /// ```
658 ///
659 /// Similar to [`flush`], all intermediately buffered is written to the
660 /// underlying stream. Once the operation completes, the caller should
661 /// no longer attempt to write to the stream. For example, the
662 /// `TcpStream` implementation will issue a `shutdown(Write)` sys call.
663 ///
664 /// # Examples
665 ///
666 /// ```no_run
667 /// use tokio::io::{self, BufWriter, AsyncWriteExt};
668 /// use tokio::fs::File;
669 ///
670 /// #[tokio::main]
671 /// async fn main() -> io::Result<()> {
672 /// let f = File::create("foo.txt").await?;
673 /// let mut buffer = BufWriter::new(f);
674 ///
675 /// buffer.write_all(b"some bytes").await?;
676 /// buffer.shutdown().await?;
677 /// Ok(())
678 /// }
679 /// ```
680 fn shutdown(&mut self) -> Shutdown<'_, Self>
681 where
682 Self: Unpin,
683 {
684 shutdown(self)
685 }
686 }
687}
688
689impl<W: AsyncWrite + ?Sized> AsyncWriteExt for W {}