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;