summaryrefslogtreecommitdiffstats
path: root/third_party/rust/tokio-io/src/lines.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/tokio-io/src/lines.rs')
-rw-r--r--third_party/rust/tokio-io/src/lines.rs62
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())
+ }
+}