Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 63f3a80

Browse files
bors[bot]Stjepan Glavina
and
Stjepan Glavina
authored
Merge #161
161: Split BufRead into multiple files r=stjepang a=stjepang Co-authored-by: Stjepan Glavina <stjepang@gmail.com>
2 parents ba43a05 + 55550c6 commit 63f3a80

File tree

4 files changed

+163
-130
lines changed

4 files changed

+163
-130
lines changed

‎src/io/buf_read/lines.rs‎

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use std::mem;
2+
use std::pin::Pin;
3+
use std::str;
4+
5+
use futures_io::AsyncBufRead;
6+
7+
use super::read_until_internal;
8+
use crate::io;
9+
use crate::task::{Context, Poll};
10+
11+
/// A stream of lines in a byte stream.
12+
///
13+
/// This stream is created by the [`lines`] method on types that implement [`BufRead`].
14+
///
15+
/// This type is an async version of [`std::io::Lines`].
16+
///
17+
/// [`lines`]: trait.BufRead.html#method.lines
18+
/// [`BufRead`]: trait.BufRead.html
19+
/// [`std::io::Lines`]: https://doc.rust-lang.org/nightly/std/io/struct.Lines.html
20+
#[derive(Debug)]
21+
pub struct Lines<R> {
22+
pub(crate) reader: R,
23+
pub(crate) buf: String,
24+
pub(crate) bytes: Vec<u8>,
25+
pub(crate) read: usize,
26+
}
27+
28+
impl<R: AsyncBufRead> futures_core::stream::Stream for Lines<R> {
29+
type Item = io::Result<String>;
30+
31+
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
32+
let Self {
33+
reader,
34+
buf,
35+
bytes,
36+
read,
37+
} = unsafe { self.get_unchecked_mut() };
38+
let reader = unsafe { Pin::new_unchecked(reader) };
39+
let n = futures_core::ready!(read_line_internal(reader, cx, buf, bytes, read))?;
40+
if n == 0 && buf.is_empty() {
41+
return Poll::Ready(None);
42+
}
43+
if buf.ends_with('\n') {
44+
buf.pop();
45+
if buf.ends_with('\r') {
46+
buf.pop();
47+
}
48+
}
49+
Poll::Ready(Some(Ok(mem::replace(buf, String::new()))))
50+
}
51+
}
52+
53+
pub fn read_line_internal<R: AsyncBufRead + ?Sized>(
54+
reader: Pin<&mut R>,
55+
cx: &mut Context<'_>,
56+
buf: &mut String,
57+
bytes: &mut Vec<u8>,
58+
read: &mut usize,
59+
) -> Poll<io::Result<usize>> {
60+
let ret = futures_core::ready!(read_until_internal(reader, cx, b'\n', bytes, read));
61+
if str::from_utf8(&bytes).is_err() {
62+
Poll::Ready(ret.and_then(|_| {
63+
Err(io::Error::new(
64+
io::ErrorKind::InvalidData,
65+
"stream did not contain valid UTF-8",
66+
))
67+
}))
68+
} else {
69+
debug_assert!(buf.is_empty());
70+
debug_assert_eq!(*read, 0);
71+
// Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`.
72+
mem::swap(unsafe { buf.as_mut_vec() }, bytes);
73+
Poll::Ready(ret)
74+
}
75+
}

‎src/io/buf_read.rs‎ renamed to ‎src/io/buf_read/mod.rs‎

Lines changed: 8 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1+
mod lines;
2+
mod read_line;
3+
mod read_until;
4+
5+
pub use lines::Lines;
6+
use read_line::ReadLineFuture;
7+
use read_until::ReadUntilFuture;
8+
19
use std::mem;
210
use std::pin::Pin;
3-
use std::str;
411

512
use cfg_if::cfg_if;
613
use futures_io::AsyncBufRead;
714

8-
use crate::future::Future;
915
use crate::io;
1016
use crate::task::{Context, Poll};
1117

@@ -191,134 +197,6 @@ pub trait BufRead {
191197

192198
impl<T: AsyncBufRead + Unpin + ?Sized> BufRead for T {}
193199

194-
#[doc(hidden)]
195-
#[allow(missing_debug_implementations)]
196-
pub struct ReadUntilFuture<'a, T: Unpin + ?Sized> {
197-
reader: &'a mut T,
198-
byte: u8,
199-
buf: &'a mut Vec<u8>,
200-
read: usize,
201-
}
202-
203-
impl<T: AsyncBufRead + Unpin + ?Sized> Future for ReadUntilFuture<'_, T> {
204-
type Output = io::Result<usize>;
205-
206-
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
207-
let Self {
208-
reader,
209-
byte,
210-
buf,
211-
read,
212-
} = &mut *self;
213-
read_until_internal(Pin::new(reader), cx, *byte, buf, read)
214-
}
215-
}
216-
217-
#[doc(hidden)]
218-
#[allow(missing_debug_implementations)]
219-
pub struct ReadLineFuture<'a, T: Unpin + ?Sized> {
220-
reader: &'a mut T,
221-
buf: &'a mut String,
222-
bytes: Vec<u8>,
223-
read: usize,
224-
}
225-
226-
impl<T: AsyncBufRead + Unpin + ?Sized> Future for ReadLineFuture<'_, T> {
227-
type Output = io::Result<usize>;
228-
229-
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
230-
let Self {
231-
reader,
232-
buf,
233-
bytes,
234-
read,
235-
} = &mut *self;
236-
let reader = Pin::new(reader);
237-
238-
let ret = futures_core::ready!(read_until_internal(reader, cx, b'\n', bytes, read));
239-
if str::from_utf8(&bytes).is_err() {
240-
Poll::Ready(ret.and_then(|_| {
241-
Err(io::Error::new(
242-
io::ErrorKind::InvalidData,
243-
"stream did not contain valid UTF-8",
244-
))
245-
}))
246-
} else {
247-
debug_assert!(buf.is_empty());
248-
debug_assert_eq!(*read, 0);
249-
// Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`.
250-
mem::swap(unsafe { buf.as_mut_vec() }, bytes);
251-
Poll::Ready(ret)
252-
}
253-
}
254-
}
255-
256-
/// A stream of lines in a byte stream.
257-
///
258-
/// This stream is created by the [`lines`] method on types that implement [`BufRead`].
259-
///
260-
/// This type is an async version of [`std::io::Lines`].
261-
///
262-
/// [`lines`]: trait.BufRead.html#method.lines
263-
/// [`BufRead`]: trait.BufRead.html
264-
/// [`std::io::Lines`]: https://doc.rust-lang.org/nightly/std/io/struct.Lines.html
265-
#[derive(Debug)]
266-
pub struct Lines<R> {
267-
reader: R,
268-
buf: String,
269-
bytes: Vec<u8>,
270-
read: usize,
271-
}
272-
273-
impl<R: AsyncBufRead> futures_core::stream::Stream for Lines<R> {
274-
type Item = io::Result<String>;
275-
276-
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
277-
let Self {
278-
reader,
279-
buf,
280-
bytes,
281-
read,
282-
} = unsafe { self.get_unchecked_mut() };
283-
let reader = unsafe { Pin::new_unchecked(reader) };
284-
let n = futures_core::ready!(read_line_internal(reader, cx, buf, bytes, read))?;
285-
if n == 0 && buf.is_empty() {
286-
return Poll::Ready(None);
287-
}
288-
if buf.ends_with('\n') {
289-
buf.pop();
290-
if buf.ends_with('\r') {
291-
buf.pop();
292-
}
293-
}
294-
Poll::Ready(Some(Ok(mem::replace(buf, String::new()))))
295-
}
296-
}
297-
298-
pub fn read_line_internal<R: AsyncBufRead + ?Sized>(
299-
reader: Pin<&mut R>,
300-
cx: &mut Context<'_>,
301-
buf: &mut String,
302-
bytes: &mut Vec<u8>,
303-
read: &mut usize,
304-
) -> Poll<io::Result<usize>> {
305-
let ret = futures_core::ready!(read_until_internal(reader, cx, b'\n', bytes, read));
306-
if str::from_utf8(&bytes).is_err() {
307-
Poll::Ready(ret.and_then(|_| {
308-
Err(io::Error::new(
309-
io::ErrorKind::InvalidData,
310-
"stream did not contain valid UTF-8",
311-
))
312-
}))
313-
} else {
314-
debug_assert!(buf.is_empty());
315-
debug_assert_eq!(*read, 0);
316-
// Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`.
317-
mem::swap(unsafe { buf.as_mut_vec() }, bytes);
318-
Poll::Ready(ret)
319-
}
320-
}
321-
322200
pub fn read_until_internal<R: AsyncBufRead + ?Sized>(
323201
mut reader: Pin<&mut R>,
324202
cx: &mut Context<'_>,

‎src/io/buf_read/read_line.rs‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use std::mem;
2+
use std::pin::Pin;
3+
use std::str;
4+
5+
use futures_io::AsyncBufRead;
6+
7+
use super::read_until_internal;
8+
use crate::future::Future;
9+
use crate::io;
10+
use crate::task::{Context, Poll};
11+
12+
#[doc(hidden)]
13+
#[allow(missing_debug_implementations)]
14+
pub struct ReadLineFuture<'a, T: Unpin + ?Sized> {
15+
pub(crate) reader: &'a mut T,
16+
pub(crate) buf: &'a mut String,
17+
pub(crate) bytes: Vec<u8>,
18+
pub(crate) read: usize,
19+
}
20+
21+
impl<T: AsyncBufRead + Unpin + ?Sized> Future for ReadLineFuture<'_, T> {
22+
type Output = io::Result<usize>;
23+
24+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
25+
let Self {
26+
reader,
27+
buf,
28+
bytes,
29+
read,
30+
} = &mut *self;
31+
let reader = Pin::new(reader);
32+
33+
let ret = futures_core::ready!(read_until_internal(reader, cx, b'\n', bytes, read));
34+
if str::from_utf8(&bytes).is_err() {
35+
Poll::Ready(ret.and_then(|_| {
36+
Err(io::Error::new(
37+
io::ErrorKind::InvalidData,
38+
"stream did not contain valid UTF-8",
39+
))
40+
}))
41+
} else {
42+
debug_assert!(buf.is_empty());
43+
debug_assert_eq!(*read, 0);
44+
// Safety: `bytes` is a valid UTF-8 because `str::from_utf8` returned `Ok`.
45+
mem::swap(unsafe { buf.as_mut_vec() }, bytes);
46+
Poll::Ready(ret)
47+
}
48+
}
49+
}

‎src/io/buf_read/read_until.rs‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use std::pin::Pin;
2+
3+
use futures_io::AsyncBufRead;
4+
5+
use super::read_until_internal;
6+
use crate::future::Future;
7+
use crate::io;
8+
use crate::task::{Context, Poll};
9+
10+
#[doc(hidden)]
11+
#[allow(missing_debug_implementations)]
12+
pub struct ReadUntilFuture<'a, T: Unpin + ?Sized> {
13+
pub(crate) reader: &'a mut T,
14+
pub(crate) byte: u8,
15+
pub(crate) buf: &'a mut Vec<u8>,
16+
pub(crate) read: usize,
17+
}
18+
19+
impl<T: AsyncBufRead + Unpin + ?Sized> Future for ReadUntilFuture<'_, T> {
20+
type Output = io::Result<usize>;
21+
22+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
23+
let Self {
24+
reader,
25+
byte,
26+
buf,
27+
read,
28+
} = &mut *self;
29+
read_until_internal(Pin::new(reader), cx, *byte, buf, read)
30+
}
31+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /