diff options
Diffstat (limited to 'third_party/rust/tokio-io/src/lines.rs')
-rw-r--r-- | third_party/rust/tokio-io/src/lines.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/third_party/rust/tokio-io/src/lines.rs b/third_party/rust/tokio-io/src/lines.rs new file mode 100644 index 0000000000..8e59ff8fa2 --- /dev/null +++ b/third_party/rust/tokio-io/src/lines.rs @@ -0,0 +1,62 @@ +use std::io::{self, BufRead}; +use std::mem; + +use futures::{Poll, Stream}; + +use AsyncRead; + +/// Combinator created by the top-level `lines` method which is a stream over +/// the lines of text on an I/O object. +#[derive(Debug)] +pub struct Lines<A> { + io: A, + line: String, +} + +/// Creates a new stream from the I/O object given representing the lines of +/// input that are found on `A`. +/// +/// This method takes an asynchronous I/O object, `a`, and returns a `Stream` of +/// lines that the object contains. The returned stream will reach its end once +/// `a` reaches EOF. +pub fn lines<A>(a: A) -> Lines<A> +where + A: AsyncRead + BufRead, +{ + Lines { + io: a, + line: String::new(), + } +} + +impl<A> Lines<A> { + /// Returns the underlying I/O object. + /// + /// Note that this may lose data already read into internal buffers. It's + /// recommended to only call this once the stream has reached its end. + pub fn into_inner(self) -> A { + self.io + } +} + +impl<A> Stream for Lines<A> +where + A: AsyncRead + BufRead, +{ + type Item = String; + type Error = io::Error; + + fn poll(&mut self) -> Poll<Option<String>, io::Error> { + let n = try_nb!(self.io.read_line(&mut self.line)); + if n == 0 && self.line.len() == 0 { + return Ok(None.into()); + } + if self.line.ends_with("\n") { + self.line.pop(); + if self.line.ends_with("\r") { + self.line.pop(); + } + } + Ok(Some(mem::replace(&mut self.line, String::new())).into()) + } +} |