      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259

    use crate::io::util::lines::{lines, Lines};
    use crate::io::util::read_line::{read_line, ReadLine};
    use crate::io::util::read_until::{read_until, ReadUntil};
    use crate::io::util::split::{split, Split};
    use crate::io::AsyncBufRead;

    cfg_io_util! {
        /// An extension trait which adds utility methods to [`AsyncBufRead`] types.
        ///
        /// [`AsyncBufRead`]: crate::io::AsyncBufRead
        pub trait AsyncBufReadExt: AsyncBufRead {
            /// Reads all bytes into `buf` until the delimiter `byte` or EOF is reached.
            ///
            /// Equivalent to:
            ///
            /// ```ignore
            /// async fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize>;
            /// ```
            ///
            /// This function will read bytes from the underlying stream until the
            /// delimiter or EOF is found. Once found, all bytes up to, and including,
            /// the delimiter (if found) will be appended to `buf`.
            ///
            /// If successful, this function will return the total number of bytes read.
            ///
            /// If this function returns `Ok(0)`, the stream has reached EOF.
            ///
            /// # Errors
            ///
            /// This function will ignore all instances of [`ErrorKind::Interrupted`] and
            /// will otherwise return any errors returned by [`fill_buf`].
            ///
            /// If an I/O error is encountered then all bytes read so far will be
            /// present in `buf` and its length will have been adjusted appropriately.
            ///
            /// [`fill_buf`]: AsyncBufRead::poll_fill_buf
            /// [`ErrorKind::Interrupted`]: std::io::ErrorKind::Interrupted
            ///
            /// # Examples
            ///
            /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
            /// this example, we use [`Cursor`] to read all the bytes in a byte slice
            /// in hyphen delimited segments:
            ///
            /// [`Cursor`]: std::io::Cursor
            ///
            /// ```
            /// use tokio::io::AsyncBufReadExt;
            ///
            /// use std::io::Cursor;
            ///
            /// #[tokio::main]
            /// async fn main() {
            ///     let mut cursor = Cursor::new(b"lorem-ipsum");
            ///     let mut buf = vec![];
            ///
            ///     // cursor is at 'l'
            ///     let num_bytes = cursor.read_until(b'-', &mut buf)
            ///         .await
            ///         .expect("reading from cursor won't fail");
            ///
            ///     assert_eq!(num_bytes, 6);
            ///     assert_eq!(buf, b"lorem-");
            ///     buf.clear();
            ///
            ///     // cursor is at 'i'
            ///     let num_bytes = cursor.read_until(b'-', &mut buf)
            ///         .await
            ///         .expect("reading from cursor won't fail");
            ///
            ///     assert_eq!(num_bytes, 5);
            ///     assert_eq!(buf, b"ipsum");
            ///     buf.clear();
            ///
            ///     // cursor is at EOF
            ///     let num_bytes = cursor.read_until(b'-', &mut buf)
            ///         .await
            ///         .expect("reading from cursor won't fail");
            ///     assert_eq!(num_bytes, 0);
            ///     assert_eq!(buf, b"");
            /// }
            /// ```
            fn read_until<'a>(&'a mut self, byte: u8, buf: &'a mut Vec<u8>) -> ReadUntil<'a, Self>
            where
                Self: Unpin,
            {
                read_until(self, byte, buf)
            }

            /// Reads all bytes until a newline (the 0xA byte) is reached, and append
            /// them to the provided buffer.
            ///
            /// Equivalent to:
            ///
            /// ```ignore
            /// async fn read_line(&mut self, buf: &mut String) -> io::Result<usize>;
            /// ```
            ///
            /// This function will read bytes from the underlying stream until the
            /// newline delimiter (the 0xA byte) or EOF is found. Once found, all bytes
            /// up to, and including, the delimiter (if found) will be appended to
            /// `buf`.
            ///
            /// If successful, this function will return the total number of bytes read.
            ///
            /// If this function returns `Ok(0)`, the stream has reached EOF.
            ///
            /// # Errors
            ///
            /// This function has the same error semantics as [`read_until`] and will
            /// also return an error if the read bytes are not valid UTF-8. If an I/O
            /// error is encountered then `buf` may contain some bytes already read in
            /// the event that all data read so far was valid UTF-8.
            ///
            /// [`read_until`]: AsyncBufReadExt::read_until
            ///
            /// # Examples
            ///
            /// [`std::io::Cursor`][`Cursor`] is a type that implements
            /// `AsyncBufRead`. In this example, we use [`Cursor`] to read all the
            /// lines in a byte slice:
            ///
            /// [`Cursor`]: std::io::Cursor
            ///
            /// ```
            /// use tokio::io::AsyncBufReadExt;
            ///
            /// use std::io::Cursor;
            ///
            /// #[tokio::main]
            /// async fn main() {
            ///     let mut cursor = Cursor::new(b"foo\nbar");
            ///     let mut buf = String::new();
            ///
            ///     // cursor is at 'f'
            ///     let num_bytes = cursor.read_line(&mut buf)
            ///         .await
            ///         .expect("reading from cursor won't fail");
            ///
            ///     assert_eq!(num_bytes, 4);
            ///     assert_eq!(buf, "foo\n");
            ///     buf.clear();
            ///
            ///     // cursor is at 'b'
            ///     let num_bytes = cursor.read_line(&mut buf)
            ///         .await
            ///         .expect("reading from cursor won't fail");
            ///
            ///     assert_eq!(num_bytes, 3);
            ///     assert_eq!(buf, "bar");
            ///     buf.clear();
            ///
            ///     // cursor is at EOF
            ///     let num_bytes = cursor.read_line(&mut buf)
            ///         .await
            ///         .expect("reading from cursor won't fail");
            ///
            ///     assert_eq!(num_bytes, 0);
            ///     assert_eq!(buf, "");
            /// }
            /// ```
            fn read_line<'a>(&'a mut self, buf: &'a mut String) -> ReadLine<'a, Self>
            where
                Self: Unpin,
            {
                read_line(self, buf)
            }

            /// Returns a stream of the contents of this reader split on the byte
            /// `byte`.
            ///
            /// This method is the asynchronous equivalent to
            /// [`BufRead::split`](std::io::BufRead::split).
            ///
            /// The stream returned from this function will yield instances of
            /// [`io::Result`]`<`[`Vec<u8>`]`>`. Each vector returned will *not* have
            /// the delimiter byte at the end.
            ///
            /// [`io::Result`]: std::io::Result
            /// [`Vec<u8>`]: std::vec::Vec
            ///
            /// # Errors
            ///
            /// Each item of the stream has the same error semantics as
            /// [`AsyncBufReadExt::read_until`](AsyncBufReadExt::read_until).
            ///
            /// # Examples
            ///
            /// ```
            /// # use tokio::io::AsyncBufRead;
            /// use tokio::io::AsyncBufReadExt;
            ///
            /// # async fn dox(my_buf_read: impl AsyncBufRead + Unpin) -> std::io::Result<()> {
            /// let mut segments = my_buf_read.split(b'f');
            ///
            /// while let Some(segment) = segments.next_segment().await? {
            ///     println!("length = {}", segment.len())
            /// }
            /// # Ok(())
            /// # }
            /// ```
            fn split(self, byte: u8) -> Split<Self>
            where
                Self: Sized + Unpin,
            {
                split(self, byte)
            }

            /// Returns a stream over the lines of this reader.
            /// This method is the async equivalent to [`BufRead::lines`](std::io::BufRead::lines).
            ///
            /// The stream returned from this function will yield instances of
            /// [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline
            /// byte (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end.
            ///
            /// [`io::Result`]: std::io::Result
            /// [`String`]: String
            ///
            /// # Errors
            ///
            /// Each line of the stream has the same error semantics as [`AsyncBufReadExt::read_line`].
            ///
            /// # Examples
            ///
            /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
            /// this example, we use [`Cursor`] to iterate over all the lines in a byte
            /// slice.
            ///
            /// [`Cursor`]: std::io::Cursor
            ///
            /// ```
            /// use tokio::io::AsyncBufReadExt;
            ///
            /// use std::io::Cursor;
            ///
            /// #[tokio::main]
            /// async fn main() {
            ///     let cursor = Cursor::new(b"lorem\nipsum\r\ndolor");
            ///
            ///     let mut lines = cursor.lines();
            ///
            ///     assert_eq!(lines.next_line().await.unwrap(), Some(String::from("lorem")));
            ///     assert_eq!(lines.next_line().await.unwrap(), Some(String::from("ipsum")));
            ///     assert_eq!(lines.next_line().await.unwrap(), Some(String::from("dolor")));
            ///     assert_eq!(lines.next_line().await.unwrap(), None);
            /// }
            /// ```
            ///
            /// [`AsyncBufReadExt::read_line`]: AsyncBufReadExt::read_line
            fn lines(self) -> Lines<Self>
            where
                Self: Sized,
            {
                lines(self)
            }
        }
    }

    impl<R: AsyncBufRead + ?Sized> AsyncBufReadExt for R {}