diff --git a/src/lib.rs b/src/lib.rs index ba0326aca..f64fdbc2f 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 b960dacfd..27efd8b70 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>>; + ) -> 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 000000000..72260a546 --- /dev/null +++ b/src/string/extend.rs @@ -0,0 +1,67 @@ +use std::borrow::Cow; +use std::pin::Pin; + +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/StreamExt + // let (lower_bound, _) = stream.size_hint(); + // self.reserve(lower_bound); + + 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, + //TODO: Remove the underscore when uncommenting the body of this impl + _stream: S, + ) -> Pin + 'a>> + where + 'b: 'a, + { + //TODO: This can be uncommented when `copied` is added to Stream/StreamExt + //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, + { + Box::pin(stream.into_stream().for_each(move |s| self.push_str(s))) + } +} + +impl Extend for String { + fn stream_extend<'a, S: IntoStream + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> { + Box::pin(stream.into_stream().for_each(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, + { + Box::pin(stream.into_stream().for_each(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 000000000..276d13a73 --- /dev/null +++ b/src/string/from_stream.rs @@ -0,0 +1,104 @@ +use std::borrow::Cow; +use std::pin::Pin; + +use crate::stream::{Extend, FromStream, IntoStream}; + +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 000000000..e382fcf2c --- /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;