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 {}