From b878855bc3396c78eaff9daf20bb0d3b07fd9142 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Sat, 28 Sep 2019 22:43:52 -0400 Subject: [PATCH] **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 ba0326ac..f64fdbc2 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 b960dacf..47dc828f 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 00000000..71d14a32 --- /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 00000000..7d3bc5bd --- /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 00000000..e382fcf2 --- /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;