From b878855bc3396c78eaff9daf20bb0d3b07fd9142 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Sat, 28 Sep 2019 22:43:52 -0400 Subject: [PATCH 1/3] **CHANGES** extend trait in order to allow FromStream impls for String --- src/lib.rs | 1 + src/stream/extend.rs | 2 +- src/string/extend.rs | 60 ++++++++++++++++++++++ src/string/from_stream.rs | 104 ++++++++++++++++++++++++++++++++++++++ src/string/mod.rs | 9 ++++ 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/string/extend.rs create mode 100644 src/string/from_stream.rs create mode 100644 src/string/mod.rs diff --git a/src/lib.rs b/src/lib.rs index ba0326a..f64fdbc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,6 +68,7 @@ cfg_if! { mod vec; mod result; mod option; + mod string; } } diff --git a/src/stream/extend.rs b/src/stream/extend.rs index b960dac..47dc828 100644 --- a/src/stream/extend.rs +++ b/src/stream/extend.rs @@ -33,7 +33,7 @@ pub trait Extend { fn stream_extend<'a, T: IntoStream + 'a>( &'a mut self, stream: T, - ) -> Pin + 'a>>; + ) -> Pin + 'a>> where A: 'a; } impl Extend<()> for () { diff --git a/src/string/extend.rs b/src/string/extend.rs new file mode 100644 index 0000000..71d14a3 --- /dev/null +++ b/src/string/extend.rs @@ -0,0 +1,60 @@ +use std::pin::Pin; +use std::borrow::Cow; + +use crate::prelude::*; +use crate::stream::{Extend, IntoStream}; + +impl Extend for String { + fn stream_extend<'a, S: IntoStream + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> { + let stream = stream.into_stream(); + //TODO: Add this back in when size_hint is added to stream + // let (lower_bound, _) = stream.size_hint(); + // self.reserve(lower_bound); + + //TODO: This can just be: stream.for_each(move |c| self.push(c)) + Box::pin(stream.fold((), move |(), c| self.push(c))) + } +} + +impl<'b> Extend<&'b char> for String { + fn stream_extend<'a, S: IntoStream + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> where 'b: 'a { + //TODO: Box::pin(stream.into_stream().copied()) + unimplemented!() + } +} + +impl<'b> Extend<&'b str> for String { + fn stream_extend<'a, S: IntoStream + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> where 'b: 'a { + //TODO: This can just be: stream.into_stream().for_each(move |s| self.push_str(s)) + Box::pin(stream.into_stream().fold((), move |(), s| self.push_str(s))) + } +} + +impl Extend for String { + fn stream_extend<'a, S: IntoStream + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> { + //TODO: This can just be: stream.into_stream().for_each(move |s| self.push_str(&s)) + Box::pin(stream.into_stream().fold((), move |(), s| self.push_str(&s))) + } +} + +impl<'b> Extend> for String { + fn stream_extend<'a, S: IntoStream> + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> where 'b: 'a { + //TODO: This can just be: stream.into_stream().for_each(move |s| self.push_str(&s)) + Box::pin(stream.into_stream().fold((), move |(), s| self.push_str(&s))) + } +} diff --git a/src/string/from_stream.rs b/src/string/from_stream.rs new file mode 100644 index 0000000..7d3bc5b --- /dev/null +++ b/src/string/from_stream.rs @@ -0,0 +1,104 @@ +use std::pin::Pin; +use std::borrow::Cow; + +use crate::stream::{FromStream, IntoStream, Extend}; + +impl FromStream for String { + #[inline] + fn from_stream<'a, S: IntoStream>( + stream: S, + ) -> Pin + 'a>> + where + ::IntoStream: 'a, + { + let stream = stream.into_stream(); + + Box::pin(async move { + pin_utils::pin_mut!(stream); + + let mut out = String::new(); + out.stream_extend(stream).await; + out + }) + } +} + +impl<'b> FromStream<&'b char> for String { + #[inline] + fn from_stream<'a, S: IntoStream>( + stream: S, + ) -> Pin + 'a>> + where + ::IntoStream: 'a, + { + let stream = stream.into_stream(); + + Box::pin(async move { + pin_utils::pin_mut!(stream); + + let mut out = String::new(); + out.stream_extend(stream).await; + out + }) + } +} + +impl<'b> FromStream<&'b str> for String { + #[inline] + fn from_stream<'a, S: IntoStream>( + stream: S, + ) -> Pin + 'a>> + where + ::IntoStream: 'a, + { + let stream = stream.into_stream(); + + Box::pin(async move { + pin_utils::pin_mut!(stream); + + let mut out = String::new(); + out.stream_extend(stream).await; + out + }) + } +} + +impl FromStream for String { + #[inline] + fn from_stream<'a, S: IntoStream>( + stream: S, + ) -> Pin + 'a>> + where + ::IntoStream: 'a, + { + let stream = stream.into_stream(); + + Box::pin(async move { + pin_utils::pin_mut!(stream); + + let mut out = String::new(); + out.stream_extend(stream).await; + out + }) + } +} + +impl<'b> FromStream> for String { + #[inline] + fn from_stream<'a, S: IntoStream>>( + stream: S, + ) -> Pin + 'a>> + where + ::IntoStream: 'a, + { + let stream = stream.into_stream(); + + Box::pin(async move { + pin_utils::pin_mut!(stream); + + let mut out = String::new(); + out.stream_extend(stream).await; + out + }) + } +} diff --git a/src/string/mod.rs b/src/string/mod.rs new file mode 100644 index 0000000..e382fcf --- /dev/null +++ b/src/string/mod.rs @@ -0,0 +1,9 @@ +//! The Rust core string library +//! +//! This library provides a UTF-8 encoded, growable string. + +mod extend; +mod from_stream; + +#[doc(inline)] +pub use std::string::String; From d6f16b6a175de09308c98f9906ac5ea04bf6e426 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Mon, 30 Sep 2019 20:13:28 -0400 Subject: [PATCH 2/3] rustfmt --- src/stream/extend.rs | 4 +++- src/string/extend.rs | 29 +++++++++++++++++++++++------ src/string/from_stream.rs | 4 ++-- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/stream/extend.rs b/src/stream/extend.rs index 47dc828..27efd8b 100644 --- a/src/stream/extend.rs +++ b/src/stream/extend.rs @@ -33,7 +33,9 @@ pub trait Extend { fn stream_extend<'a, T: IntoStream + 'a>( &'a mut self, stream: T, - ) -> Pin + 'a>> where A: 'a; + ) -> Pin + 'a>> + where + A: 'a; } impl Extend<()> for () { diff --git a/src/string/extend.rs b/src/string/extend.rs index 71d14a3..feac1a4 100644 --- a/src/string/extend.rs +++ b/src/string/extend.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::borrow::Cow; +use std::pin::Pin; use crate::prelude::*; use crate::stream::{Extend, IntoStream}; @@ -23,7 +23,10 @@ impl<'b> Extend<&'b char> for String { fn stream_extend<'a, S: IntoStream + 'a>( &'a mut self, stream: S, - ) -> Pin + 'a>> where 'b: 'a { + ) -> Pin + 'a>> + where + 'b: 'a, + { //TODO: Box::pin(stream.into_stream().copied()) unimplemented!() } @@ -33,7 +36,10 @@ impl<'b> Extend<&'b str> for String { fn stream_extend<'a, S: IntoStream + 'a>( &'a mut self, stream: S, - ) -> Pin + 'a>> where 'b: 'a { + ) -> Pin + 'a>> + where + 'b: 'a, + { //TODO: This can just be: stream.into_stream().for_each(move |s| self.push_str(s)) Box::pin(stream.into_stream().fold((), move |(), s| self.push_str(s))) } @@ -45,7 +51,11 @@ impl Extend for String { stream: S, ) -> Pin + 'a>> { //TODO: This can just be: stream.into_stream().for_each(move |s| self.push_str(&s)) - Box::pin(stream.into_stream().fold((), move |(), s| self.push_str(&s))) + Box::pin( + stream + .into_stream() + .fold((), move |(), s| self.push_str(&s)), + ) } } @@ -53,8 +63,15 @@ impl<'b> Extend> for String { fn stream_extend<'a, S: IntoStream> + 'a>( &'a mut self, stream: S, - ) -> Pin + 'a>> where 'b: 'a { + ) -> Pin + 'a>> + where + 'b: 'a, + { //TODO: This can just be: stream.into_stream().for_each(move |s| self.push_str(&s)) - Box::pin(stream.into_stream().fold((), move |(), s| self.push_str(&s))) + Box::pin( + stream + .into_stream() + .fold((), move |(), s| self.push_str(&s)), + ) } } diff --git a/src/string/from_stream.rs b/src/string/from_stream.rs index 7d3bc5b..276d13a 100644 --- a/src/string/from_stream.rs +++ b/src/string/from_stream.rs @@ -1,7 +1,7 @@ -use std::pin::Pin; use std::borrow::Cow; +use std::pin::Pin; -use crate::stream::{FromStream, IntoStream, Extend}; +use crate::stream::{Extend, FromStream, IntoStream}; impl FromStream for String { #[inline] From 09a15ef116aa1b66f13d7bd2cae05ca7ef44fb5a Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Tue, 1 Oct 2019 22:39:57 -0400 Subject: [PATCH 3/3] Implementing Extend for String in terms of for_each now that that's been added --- src/string/extend.rs | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/string/extend.rs b/src/string/extend.rs index feac1a4..72260a5 100644 --- a/src/string/extend.rs +++ b/src/string/extend.rs @@ -10,24 +10,25 @@ impl Extend for String { stream: S, ) -> Pin + 'a>> { let stream = stream.into_stream(); - //TODO: Add this back in when size_hint is added to stream + //TODO: Add this back in when size_hint is added to Stream/StreamExt // let (lower_bound, _) = stream.size_hint(); // self.reserve(lower_bound); - //TODO: This can just be: stream.for_each(move |c| self.push(c)) - Box::pin(stream.fold((), move |(), c| self.push(c))) + Box::pin(stream.for_each(move |c| self.push(c))) } } impl<'b> Extend<&'b char> for String { fn stream_extend<'a, S: IntoStream + 'a>( &'a mut self, - stream: S, + //TODO: Remove the underscore when uncommenting the body of this impl + _stream: S, ) -> Pin + 'a>> where 'b: 'a, { - //TODO: Box::pin(stream.into_stream().copied()) + //TODO: This can be uncommented when `copied` is added to Stream/StreamExt + //Box::pin(stream.into_stream().copied()) unimplemented!() } } @@ -40,8 +41,7 @@ impl<'b> Extend<&'b str> for String { where 'b: 'a, { - //TODO: This can just be: stream.into_stream().for_each(move |s| self.push_str(s)) - Box::pin(stream.into_stream().fold((), move |(), s| self.push_str(s))) + Box::pin(stream.into_stream().for_each(move |s| self.push_str(s))) } } @@ -50,12 +50,7 @@ impl Extend for String { &'a mut self, stream: S, ) -> Pin + 'a>> { - //TODO: This can just be: stream.into_stream().for_each(move |s| self.push_str(&s)) - Box::pin( - stream - .into_stream() - .fold((), move |(), s| self.push_str(&s)), - ) + Box::pin(stream.into_stream().for_each(move |s| self.push_str(&s))) } } @@ -67,11 +62,6 @@ impl<'b> Extend> for String { where 'b: 'a, { - //TODO: This can just be: stream.into_stream().for_each(move |s| self.push_str(&s)) - Box::pin( - stream - .into_stream() - .fold((), move |(), s| self.push_str(&s)), - ) + Box::pin(stream.into_stream().for_each(move |s| self.push_str(&s))) } }