From 6bc3cd0ab2777b578f552b3e3d8bf0b6c3d2967a Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Sat, 28 Sep 2019 22:10:22 -0400 Subject: [PATCH 01/13] FromStream for () --- src/lib.rs | 1 + src/unit/from_stream.rs | 16 ++++++++++++++++ src/unit/mod.rs | 6 ++++++ 3 files changed, 23 insertions(+) create mode 100644 src/unit/from_stream.rs create mode 100644 src/unit/mod.rs diff --git a/src/lib.rs b/src/lib.rs index f64fdbc2..3b0aa699 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,6 +65,7 @@ cfg_if! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] pub mod pin; + mod unit; mod vec; mod result; mod option; diff --git a/src/unit/from_stream.rs b/src/unit/from_stream.rs new file mode 100644 index 00000000..a238982d --- /dev/null +++ b/src/unit/from_stream.rs @@ -0,0 +1,16 @@ +use std::pin::Pin; + +use crate::prelude::*; +use crate::stream::{FromStream, IntoStream}; + +impl FromStream<()> for () { + #[inline] + fn from_stream<'a, S: IntoStream>( + stream: S, + ) -> Pin + 'a>> + where + ::IntoStream: 'a, + { + Box::pin(stream.into_stream().for_each(|_| ())) + } +} diff --git a/src/unit/mod.rs b/src/unit/mod.rs new file mode 100644 index 00000000..cb8063d0 --- /dev/null +++ b/src/unit/mod.rs @@ -0,0 +1,6 @@ +//! The Rust primitive `()` type, sometimes called "unit" or "nil". +//! +//! This module provides types and implementations for working +//! asynchronously with values of type `()`. + +mod from_stream; From ae146afffccb97a33d3bddec79136b30c8cf70b8 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Tue, 1 Oct 2019 23:11:57 -0400 Subject: [PATCH 02/13] FromStream + Extend for VecDeque --- src/collections/mod.rs | 8 ++++++++ src/collections/vec_deque/extend.rs | 18 ++++++++++++++++++ src/collections/vec_deque/from_stream.rs | 24 ++++++++++++++++++++++++ src/collections/vec_deque/mod.rs | 7 +++++++ src/lib.rs | 1 + 5 files changed, 58 insertions(+) create mode 100644 src/collections/mod.rs create mode 100644 src/collections/vec_deque/extend.rs create mode 100644 src/collections/vec_deque/from_stream.rs create mode 100644 src/collections/vec_deque/mod.rs diff --git a/src/collections/mod.rs b/src/collections/mod.rs new file mode 100644 index 00000000..e20a321a --- /dev/null +++ b/src/collections/mod.rs @@ -0,0 +1,8 @@ +//! The Rust standard collections +//! +//! This library provides efficient implementations of the most common general purpose programming +//! data structures. + +mod vec_deque; + +pub use vec_deque::*; diff --git a/src/collections/vec_deque/extend.rs b/src/collections/vec_deque/extend.rs new file mode 100644 index 00000000..b8884d81 --- /dev/null +++ b/src/collections/vec_deque/extend.rs @@ -0,0 +1,18 @@ +use std::pin::Pin; +use std::collections::VecDeque; + +use crate::prelude::*; +use crate::stream::{Extend, IntoStream}; + +impl Extend for VecDeque { + 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 |item| self.push_back(item))) + } +} diff --git a/src/collections/vec_deque/from_stream.rs b/src/collections/vec_deque/from_stream.rs new file mode 100644 index 00000000..ef92a49c --- /dev/null +++ b/src/collections/vec_deque/from_stream.rs @@ -0,0 +1,24 @@ +use std::pin::Pin; +use std::collections::VecDeque; + +use crate::stream::{Extend, FromStream, IntoStream}; + +impl FromStream for VecDeque { + #[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 = VecDeque::new(); + out.stream_extend(stream).await; + out + }) + } +} diff --git a/src/collections/vec_deque/mod.rs b/src/collections/vec_deque/mod.rs new file mode 100644 index 00000000..b03d5e6d --- /dev/null +++ b/src/collections/vec_deque/mod.rs @@ -0,0 +1,7 @@ +//! The Rust double-ended queue, implemented with a growable ring buffer. + +mod extend; +mod from_stream; + +#[doc(inline)] +pub use std::collections::VecDeque; diff --git a/src/lib.rs b/src/lib.rs index 3b0aa699..839a0ec2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,6 +70,7 @@ cfg_if! { mod result; mod option; mod string; + mod collections; } } From 244c5159df66b45d1ced0b0a00b0b90fae55f3e4 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Tue, 1 Oct 2019 23:12:13 -0400 Subject: [PATCH 03/13] Simplifying + optimizing Extend impl for Vec --- src/vec/extend.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/vec/extend.rs b/src/vec/extend.rs index d85589ef..ca3373d6 100644 --- a/src/vec/extend.rs +++ b/src/vec/extend.rs @@ -9,11 +9,9 @@ impl Extend for Vec { stream: S, ) -> Pin + 'a>> { let stream = stream.into_stream(); - Box::pin(async move { - pin_utils::pin_mut!(stream); - while let Some(item) = stream.next().await { - self.push(item); - } - }) + //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 |item| self.push(item))) } } From de2bc1e83b981254bd035fee06c367dc1529e086 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Tue, 1 Oct 2019 23:22:01 -0400 Subject: [PATCH 04/13] Added FromStream + Extend for BTreeMap --- src/collections/btree_map/extend.rs | 16 ++++++++++++++++ src/collections/btree_map/from_stream.rs | 24 ++++++++++++++++++++++++ src/collections/btree_map/mod.rs | 7 +++++++ src/collections/mod.rs | 6 ++++-- 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/collections/btree_map/extend.rs create mode 100644 src/collections/btree_map/from_stream.rs create mode 100644 src/collections/btree_map/mod.rs diff --git a/src/collections/btree_map/extend.rs b/src/collections/btree_map/extend.rs new file mode 100644 index 00000000..2e20848e --- /dev/null +++ b/src/collections/btree_map/extend.rs @@ -0,0 +1,16 @@ +use std::pin::Pin; +use std::collections::BTreeMap; + +use crate::prelude::*; +use crate::stream::{Extend, IntoStream}; + +impl Extend<(K, V)> for BTreeMap { + fn stream_extend<'a, S: IntoStream + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> { + Box::pin(stream.into_stream().for_each(move |(k, v)| { + self.insert(k, v); + })) + } +} diff --git a/src/collections/btree_map/from_stream.rs b/src/collections/btree_map/from_stream.rs new file mode 100644 index 00000000..cdc51b99 --- /dev/null +++ b/src/collections/btree_map/from_stream.rs @@ -0,0 +1,24 @@ +use std::pin::Pin; +use std::collections::BTreeMap; + +use crate::stream::{Extend, FromStream, IntoStream}; + +impl FromStream<(K, V)> for BTreeMap { + #[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 = BTreeMap::new(); + out.stream_extend(stream).await; + out + }) + } +} diff --git a/src/collections/btree_map/mod.rs b/src/collections/btree_map/mod.rs new file mode 100644 index 00000000..49f9084a --- /dev/null +++ b/src/collections/btree_map/mod.rs @@ -0,0 +1,7 @@ +//! The Rust B-Tree Map + +mod extend; +mod from_stream; + +#[doc(inline)] +pub use std::collections::BTreeMap; diff --git a/src/collections/mod.rs b/src/collections/mod.rs index e20a321a..8dec302c 100644 --- a/src/collections/mod.rs +++ b/src/collections/mod.rs @@ -3,6 +3,8 @@ //! This library provides efficient implementations of the most common general purpose programming //! data structures. -mod vec_deque; +pub mod vec_deque; +pub mod btree_map; -pub use vec_deque::*; +pub use vec_deque::VecDeque; +pub use btree_map::BTreeMap; From 333f35338e725cd5a41974394bea2ffe5a34a8ad Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Tue, 1 Oct 2019 23:37:06 -0400 Subject: [PATCH 05/13] Added FromStream and Extend impls for HashMap --- src/collections/hash_map/extend.rs | 36 +++++++++++++++++++++++++ src/collections/hash_map/from_stream.rs | 27 +++++++++++++++++++ src/collections/hash_map/mod.rs | 7 +++++ src/collections/mod.rs | 2 ++ 4 files changed, 72 insertions(+) create mode 100644 src/collections/hash_map/extend.rs create mode 100644 src/collections/hash_map/from_stream.rs create mode 100644 src/collections/hash_map/mod.rs diff --git a/src/collections/hash_map/extend.rs b/src/collections/hash_map/extend.rs new file mode 100644 index 00000000..68bc79e3 --- /dev/null +++ b/src/collections/hash_map/extend.rs @@ -0,0 +1,36 @@ +use std::pin::Pin; +use std::hash::{Hash, BuildHasher}; +use std::collections::HashMap; + +use crate::prelude::*; +use crate::stream::{Extend, IntoStream}; + +impl Extend<(K, V)> for HashMap +where K: Eq + Hash, + H: BuildHasher + Default { + fn stream_extend<'a, S: IntoStream + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> { + let stream = stream.into_stream(); + + // The following is adapted from the hashbrown source code: + // https://github.com/rust-lang/hashbrown/blob/d1ad4fc3aae2ade446738eea512e50b9e863dd0c/src/map.rs#L2470-L2491 + // + // Keys may be already present or show multiple times in the stream. Reserve the entire + // hint lower bound if the map is empty. Otherwise reserve half the hint (rounded up), so + // the map will only resize twice in the worst case. + + //TODO: Add this back in when size_hint is added to Stream/StreamExt + //let reserve = if self.is_empty() { + // stream.size_hint().0 + //} else { + // (stream.size_hint().0 + 1) / 2 + //}; + //self.reserve(reserve); + + Box::pin(stream.for_each(move |(k, v)| { + self.insert(k, v); + })) + } +} diff --git a/src/collections/hash_map/from_stream.rs b/src/collections/hash_map/from_stream.rs new file mode 100644 index 00000000..f9295cb0 --- /dev/null +++ b/src/collections/hash_map/from_stream.rs @@ -0,0 +1,27 @@ +use std::pin::Pin; +use std::hash::{Hash, BuildHasher}; +use std::collections::HashMap; + +use crate::stream::{Extend, FromStream, IntoStream}; + +impl FromStream<(K, V)> for HashMap +where K: Eq + Hash, + H: BuildHasher + Default { + #[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 = HashMap::with_hasher(Default::default()); + out.stream_extend(stream).await; + out + }) + } +} diff --git a/src/collections/hash_map/mod.rs b/src/collections/hash_map/mod.rs new file mode 100644 index 00000000..6e52dd21 --- /dev/null +++ b/src/collections/hash_map/mod.rs @@ -0,0 +1,7 @@ +//! The Rust hash map, implemented with quadratic probing and SIMD lookup. + +mod extend; +mod from_stream; + +#[doc(inline)] +pub use std::collections::HashMap; diff --git a/src/collections/mod.rs b/src/collections/mod.rs index 8dec302c..93a0614d 100644 --- a/src/collections/mod.rs +++ b/src/collections/mod.rs @@ -4,7 +4,9 @@ //! data structures. pub mod vec_deque; +pub mod hash_map; pub mod btree_map; pub use vec_deque::VecDeque; +pub use hash_map::HashMap; pub use btree_map::BTreeMap; From 6c2ffd71811cd4a14b91553242c77a0d18e547f5 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Wed, 2 Oct 2019 20:50:13 -0400 Subject: [PATCH 06/13] Added FromStream + Extend for HashSet --- src/collections/hash_set/extend.rs | 39 +++++++++++++++++++++++++ src/collections/hash_set/from_stream.rs | 27 +++++++++++++++++ src/collections/hash_set/mod.rs | 7 +++++ src/collections/mod.rs | 2 ++ 4 files changed, 75 insertions(+) create mode 100644 src/collections/hash_set/extend.rs create mode 100644 src/collections/hash_set/from_stream.rs create mode 100644 src/collections/hash_set/mod.rs diff --git a/src/collections/hash_set/extend.rs b/src/collections/hash_set/extend.rs new file mode 100644 index 00000000..b06e7b8c --- /dev/null +++ b/src/collections/hash_set/extend.rs @@ -0,0 +1,39 @@ +use std::pin::Pin; +use std::hash::{Hash, BuildHasher}; +use std::collections::HashSet; + +use crate::prelude::*; +use crate::stream::{Extend, IntoStream}; + +impl Extend for HashSet +where T: Eq + Hash, + H: BuildHasher + Default { + fn stream_extend<'a, S: IntoStream + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> { + // The Extend impl for HashSet in the standard library delegates to the internal HashMap. + // Thus, this impl is just a copy of the async Extend impl for HashMap in this crate. + + let stream = stream.into_stream(); + + // The following is adapted from the hashbrown source code: + // https://github.com/rust-lang/hashbrown/blob/d1ad4fc3aae2ade446738eea512e50b9e863dd0c/src/map.rs#L2470-L2491 + // + // Keys may be already present or show multiple times in the stream. Reserve the entire + // hint lower bound if the map is empty. Otherwise reserve half the hint (rounded up), so + // the map will only resize twice in the worst case. + + //TODO: Add this back in when size_hint is added to Stream/StreamExt + //let reserve = if self.is_empty() { + // stream.size_hint().0 + //} else { + // (stream.size_hint().0 + 1) / 2 + //}; + //self.reserve(reserve); + + Box::pin(stream.for_each(move |item| { + self.insert(item); + })) + } +} diff --git a/src/collections/hash_set/from_stream.rs b/src/collections/hash_set/from_stream.rs new file mode 100644 index 00000000..3714ae8e --- /dev/null +++ b/src/collections/hash_set/from_stream.rs @@ -0,0 +1,27 @@ +use std::pin::Pin; +use std::hash::{Hash, BuildHasher}; +use std::collections::HashSet; + +use crate::stream::{Extend, FromStream, IntoStream}; + +impl FromStream for HashSet +where T: Eq + Hash, + H: BuildHasher + Default { + #[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 = HashSet::with_hasher(Default::default()); + out.stream_extend(stream).await; + out + }) + } +} diff --git a/src/collections/hash_set/mod.rs b/src/collections/hash_set/mod.rs new file mode 100644 index 00000000..5d93a888 --- /dev/null +++ b/src/collections/hash_set/mod.rs @@ -0,0 +1,7 @@ +//! The Rust hash set, implemented as a `HashMap` where the value is `()`. + +mod extend; +mod from_stream; + +#[doc(inline)] +pub use std::collections::HashSet; diff --git a/src/collections/mod.rs b/src/collections/mod.rs index 93a0614d..4ed8e359 100644 --- a/src/collections/mod.rs +++ b/src/collections/mod.rs @@ -5,8 +5,10 @@ pub mod vec_deque; pub mod hash_map; +pub mod hash_set; pub mod btree_map; pub use vec_deque::VecDeque; pub use hash_map::HashMap; +pub use hash_set::HashSet; pub use btree_map::BTreeMap; From 3160dc8189dbcf7f982b9ed3cab2089b97e75046 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Wed, 2 Oct 2019 20:54:02 -0400 Subject: [PATCH 07/13] Added FromStream + Extend for BTreeSet --- src/collections/btree_set/extend.rs | 16 ++++++++++++++++ src/collections/btree_set/from_stream.rs | 24 ++++++++++++++++++++++++ src/collections/btree_set/mod.rs | 7 +++++++ src/collections/mod.rs | 2 ++ 4 files changed, 49 insertions(+) create mode 100644 src/collections/btree_set/extend.rs create mode 100644 src/collections/btree_set/from_stream.rs create mode 100644 src/collections/btree_set/mod.rs diff --git a/src/collections/btree_set/extend.rs b/src/collections/btree_set/extend.rs new file mode 100644 index 00000000..2fd1d1d8 --- /dev/null +++ b/src/collections/btree_set/extend.rs @@ -0,0 +1,16 @@ +use std::pin::Pin; +use std::collections::BTreeSet; + +use crate::prelude::*; +use crate::stream::{Extend, IntoStream}; + +impl Extend for BTreeSet { + fn stream_extend<'a, S: IntoStream + 'a>( + &'a mut self, + stream: S, + ) -> Pin + 'a>> { + Box::pin(stream.into_stream().for_each(move |item| { + self.insert(item); + })) + } +} diff --git a/src/collections/btree_set/from_stream.rs b/src/collections/btree_set/from_stream.rs new file mode 100644 index 00000000..b4b654f5 --- /dev/null +++ b/src/collections/btree_set/from_stream.rs @@ -0,0 +1,24 @@ +use std::pin::Pin; +use std::collections::BTreeSet; + +use crate::stream::{Extend, FromStream, IntoStream}; + +impl FromStream for BTreeSet { + #[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 = BTreeSet::new(); + out.stream_extend(stream).await; + out + }) + } +} diff --git a/src/collections/btree_set/mod.rs b/src/collections/btree_set/mod.rs new file mode 100644 index 00000000..e8a572ab --- /dev/null +++ b/src/collections/btree_set/mod.rs @@ -0,0 +1,7 @@ +//! The Rust B-Tree Set + +mod extend; +mod from_stream; + +#[doc(inline)] +pub use std::collections::BTreeSet; diff --git a/src/collections/mod.rs b/src/collections/mod.rs index 4ed8e359..d77d443f 100644 --- a/src/collections/mod.rs +++ b/src/collections/mod.rs @@ -7,8 +7,10 @@ pub mod vec_deque; pub mod hash_map; pub mod hash_set; pub mod btree_map; +pub mod btree_set; pub use vec_deque::VecDeque; pub use hash_map::HashMap; pub use hash_set::HashSet; pub use btree_map::BTreeMap; +pub use btree_set::BTreeSet; From bd0808eedd2827a2c44ff7faf615f1923c96d330 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Wed, 2 Oct 2019 20:59:42 -0400 Subject: [PATCH 08/13] Added FromStream + Extend for BinaryHeap --- src/collections/binary_heap/extend.rs | 18 ++++++++++++++++ src/collections/binary_heap/from_stream.rs | 24 ++++++++++++++++++++++ src/collections/binary_heap/mod.rs | 7 +++++++ src/collections/mod.rs | 2 ++ 4 files changed, 51 insertions(+) create mode 100644 src/collections/binary_heap/extend.rs create mode 100644 src/collections/binary_heap/from_stream.rs create mode 100644 src/collections/binary_heap/mod.rs diff --git a/src/collections/binary_heap/extend.rs b/src/collections/binary_heap/extend.rs new file mode 100644 index 00000000..17098d9c --- /dev/null +++ b/src/collections/binary_heap/extend.rs @@ -0,0 +1,18 @@ +use std::pin::Pin; +use std::collections::BinaryHeap; + +use crate::prelude::*; +use crate::stream::{Extend, IntoStream}; + +impl Extend for BinaryHeap { + 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 |item| self.push(item))) + } +} diff --git a/src/collections/binary_heap/from_stream.rs b/src/collections/binary_heap/from_stream.rs new file mode 100644 index 00000000..96e55473 --- /dev/null +++ b/src/collections/binary_heap/from_stream.rs @@ -0,0 +1,24 @@ +use std::pin::Pin; +use std::collections::BinaryHeap; + +use crate::stream::{Extend, FromStream, IntoStream}; + +impl FromStream for BinaryHeap { + #[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 = BinaryHeap::new(); + out.stream_extend(stream).await; + out + }) + } +} diff --git a/src/collections/binary_heap/mod.rs b/src/collections/binary_heap/mod.rs new file mode 100644 index 00000000..35c406c0 --- /dev/null +++ b/src/collections/binary_heap/mod.rs @@ -0,0 +1,7 @@ +//! The Rust priority queue implemented with a binary heap + +mod extend; +mod from_stream; + +#[doc(inline)] +pub use std::collections::BinaryHeap; diff --git a/src/collections/mod.rs b/src/collections/mod.rs index d77d443f..68c1a7d9 100644 --- a/src/collections/mod.rs +++ b/src/collections/mod.rs @@ -8,9 +8,11 @@ pub mod hash_map; pub mod hash_set; pub mod btree_map; pub mod btree_set; +pub mod binary_heap; pub use vec_deque::VecDeque; pub use hash_map::HashMap; pub use hash_set::HashSet; pub use btree_map::BTreeMap; pub use btree_set::BTreeSet; +pub use binary_heap::BinaryHeap; From b2174576b27b4995cea5cc40754933b33370d990 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Wed, 2 Oct 2019 21:03:54 -0400 Subject: [PATCH 09/13] Added FromStream + Extend for LinkedList --- src/collections/linked_list/extend.rs | 18 ++++++++++++++++ src/collections/linked_list/from_stream.rs | 24 ++++++++++++++++++++++ src/collections/linked_list/mod.rs | 7 +++++++ src/collections/mod.rs | 2 ++ 4 files changed, 51 insertions(+) create mode 100644 src/collections/linked_list/extend.rs create mode 100644 src/collections/linked_list/from_stream.rs create mode 100644 src/collections/linked_list/mod.rs diff --git a/src/collections/linked_list/extend.rs b/src/collections/linked_list/extend.rs new file mode 100644 index 00000000..8f825470 --- /dev/null +++ b/src/collections/linked_list/extend.rs @@ -0,0 +1,18 @@ +use std::pin::Pin; +use std::collections::LinkedList; + +use crate::prelude::*; +use crate::stream::{Extend, IntoStream}; + +impl Extend for LinkedList { + 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 |item| self.push_back(item))) + } +} diff --git a/src/collections/linked_list/from_stream.rs b/src/collections/linked_list/from_stream.rs new file mode 100644 index 00000000..40b1100f --- /dev/null +++ b/src/collections/linked_list/from_stream.rs @@ -0,0 +1,24 @@ +use std::pin::Pin; +use std::collections::LinkedList; + +use crate::stream::{Extend, FromStream, IntoStream}; + +impl FromStream for LinkedList { + #[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 = LinkedList::new(); + out.stream_extend(stream).await; + out + }) + } +} diff --git a/src/collections/linked_list/mod.rs b/src/collections/linked_list/mod.rs new file mode 100644 index 00000000..bd009ea7 --- /dev/null +++ b/src/collections/linked_list/mod.rs @@ -0,0 +1,7 @@ +//! The Rust doubly-linked list with owned nodes + +mod extend; +mod from_stream; + +#[doc(inline)] +pub use std::collections::LinkedList; diff --git a/src/collections/mod.rs b/src/collections/mod.rs index 68c1a7d9..2ccdb23a 100644 --- a/src/collections/mod.rs +++ b/src/collections/mod.rs @@ -9,6 +9,7 @@ pub mod hash_set; pub mod btree_map; pub mod btree_set; pub mod binary_heap; +pub mod linked_list; pub use vec_deque::VecDeque; pub use hash_map::HashMap; @@ -16,3 +17,4 @@ pub use hash_set::HashSet; pub use btree_map::BTreeMap; pub use btree_set::BTreeSet; pub use binary_heap::BinaryHeap; +pub use linked_list::LinkedList; From 8e127980389719aa9c2a16c832bce7eb579ba084 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Wed, 2 Oct 2019 21:11:50 -0400 Subject: [PATCH 10/13] impl FromStream for Cow<[T]> --- src/vec/from_stream.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/vec/from_stream.rs b/src/vec/from_stream.rs index 26196af9..8d723b49 100644 --- a/src/vec/from_stream.rs +++ b/src/vec/from_stream.rs @@ -1,4 +1,5 @@ use std::pin::Pin; +use std::borrow::Cow; use crate::stream::{Extend, FromStream, IntoStream}; @@ -21,3 +22,21 @@ impl FromStream for Vec { }) } } + +impl<'b, T: Clone> FromStream for Cow<'b, [T]> { + #[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); + + Cow::Owned(FromStream::from_stream(stream).await) + }) + } +} From 63c6b1cb635559eefe21af5b13fbdf710b299dc3 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Wed, 2 Oct 2019 21:12:31 -0400 Subject: [PATCH 11/13] impl FromStream for Box<[T]> --- src/vec/from_stream.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/vec/from_stream.rs b/src/vec/from_stream.rs index 8d723b49..c813d499 100644 --- a/src/vec/from_stream.rs +++ b/src/vec/from_stream.rs @@ -40,3 +40,21 @@ impl<'b, T: Clone> FromStream for Cow<'b, [T]> { }) } } + +impl FromStream for Box<[T]> { + #[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); + + Vec::from_stream(stream).await.into_boxed_slice() + }) + } +} From 2cf3f3f566b11a8aa46254253189dd4a7ae716fe Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Wed, 2 Oct 2019 21:15:19 -0400 Subject: [PATCH 12/13] FromStream for Arc<[T]> and Rc<[T]> --- src/vec/from_stream.rs | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/vec/from_stream.rs b/src/vec/from_stream.rs index c813d499..f4ca9a99 100644 --- a/src/vec/from_stream.rs +++ b/src/vec/from_stream.rs @@ -1,5 +1,7 @@ use std::pin::Pin; use std::borrow::Cow; +use std::sync::Arc; +use std::rc::Rc; use crate::stream::{Extend, FromStream, IntoStream}; @@ -58,3 +60,39 @@ impl FromStream for Box<[T]> { }) } } + +impl FromStream for Rc<[T]> { + #[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); + + Vec::from_stream(stream).await.into() + }) + } +} + +impl FromStream for Arc<[T]> { + #[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); + + Vec::from_stream(stream).await.into() + }) + } +} From f968c9a54080aca70b9b64c3224dd4fa989873d7 Mon Sep 17 00:00:00 2001 From: Sunjay Varma Date: Wed, 2 Oct 2019 21:17:59 -0400 Subject: [PATCH 13/13] rustfmt --- src/collections/binary_heap/extend.rs | 2 +- src/collections/binary_heap/from_stream.rs | 2 +- src/collections/btree_map/extend.rs | 2 +- src/collections/btree_map/from_stream.rs | 2 +- src/collections/btree_set/extend.rs | 2 +- src/collections/btree_set/from_stream.rs | 2 +- src/collections/hash_map/extend.rs | 10 ++++++---- src/collections/hash_map/from_stream.rs | 10 ++++++---- src/collections/hash_set/extend.rs | 10 ++++++---- src/collections/hash_set/from_stream.rs | 10 ++++++---- src/collections/linked_list/extend.rs | 2 +- src/collections/linked_list/from_stream.rs | 2 +- src/collections/mod.rs | 16 ++++++++-------- src/collections/vec_deque/extend.rs | 2 +- src/collections/vec_deque/from_stream.rs | 2 +- src/vec/from_stream.rs | 4 ++-- 16 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/collections/binary_heap/extend.rs b/src/collections/binary_heap/extend.rs index 17098d9c..8538f9b0 100644 --- a/src/collections/binary_heap/extend.rs +++ b/src/collections/binary_heap/extend.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::BinaryHeap; +use std::pin::Pin; use crate::prelude::*; use crate::stream::{Extend, IntoStream}; diff --git a/src/collections/binary_heap/from_stream.rs b/src/collections/binary_heap/from_stream.rs index 96e55473..c8e44e93 100644 --- a/src/collections/binary_heap/from_stream.rs +++ b/src/collections/binary_heap/from_stream.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::BinaryHeap; +use std::pin::Pin; use crate::stream::{Extend, FromStream, IntoStream}; diff --git a/src/collections/btree_map/extend.rs b/src/collections/btree_map/extend.rs index 2e20848e..ae02c424 100644 --- a/src/collections/btree_map/extend.rs +++ b/src/collections/btree_map/extend.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::BTreeMap; +use std::pin::Pin; use crate::prelude::*; use crate::stream::{Extend, IntoStream}; diff --git a/src/collections/btree_map/from_stream.rs b/src/collections/btree_map/from_stream.rs index cdc51b99..bd80c069 100644 --- a/src/collections/btree_map/from_stream.rs +++ b/src/collections/btree_map/from_stream.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::BTreeMap; +use std::pin::Pin; use crate::stream::{Extend, FromStream, IntoStream}; diff --git a/src/collections/btree_set/extend.rs b/src/collections/btree_set/extend.rs index 2fd1d1d8..ccf03378 100644 --- a/src/collections/btree_set/extend.rs +++ b/src/collections/btree_set/extend.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::BTreeSet; +use std::pin::Pin; use crate::prelude::*; use crate::stream::{Extend, IntoStream}; diff --git a/src/collections/btree_set/from_stream.rs b/src/collections/btree_set/from_stream.rs index b4b654f5..bd2a744b 100644 --- a/src/collections/btree_set/from_stream.rs +++ b/src/collections/btree_set/from_stream.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::BTreeSet; +use std::pin::Pin; use crate::stream::{Extend, FromStream, IntoStream}; diff --git a/src/collections/hash_map/extend.rs b/src/collections/hash_map/extend.rs index 68bc79e3..5f96b8ab 100644 --- a/src/collections/hash_map/extend.rs +++ b/src/collections/hash_map/extend.rs @@ -1,13 +1,15 @@ -use std::pin::Pin; -use std::hash::{Hash, BuildHasher}; use std::collections::HashMap; +use std::hash::{BuildHasher, Hash}; +use std::pin::Pin; use crate::prelude::*; use crate::stream::{Extend, IntoStream}; impl Extend<(K, V)> for HashMap -where K: Eq + Hash, - H: BuildHasher + Default { +where + K: Eq + Hash, + H: BuildHasher + Default, +{ fn stream_extend<'a, S: IntoStream + 'a>( &'a mut self, stream: S, diff --git a/src/collections/hash_map/from_stream.rs b/src/collections/hash_map/from_stream.rs index f9295cb0..2b7bbc9b 100644 --- a/src/collections/hash_map/from_stream.rs +++ b/src/collections/hash_map/from_stream.rs @@ -1,12 +1,14 @@ -use std::pin::Pin; -use std::hash::{Hash, BuildHasher}; use std::collections::HashMap; +use std::hash::{BuildHasher, Hash}; +use std::pin::Pin; use crate::stream::{Extend, FromStream, IntoStream}; impl FromStream<(K, V)> for HashMap -where K: Eq + Hash, - H: BuildHasher + Default { +where + K: Eq + Hash, + H: BuildHasher + Default, +{ #[inline] fn from_stream<'a, S: IntoStream>( stream: S, diff --git a/src/collections/hash_set/extend.rs b/src/collections/hash_set/extend.rs index b06e7b8c..72400e11 100644 --- a/src/collections/hash_set/extend.rs +++ b/src/collections/hash_set/extend.rs @@ -1,13 +1,15 @@ -use std::pin::Pin; -use std::hash::{Hash, BuildHasher}; use std::collections::HashSet; +use std::hash::{BuildHasher, Hash}; +use std::pin::Pin; use crate::prelude::*; use crate::stream::{Extend, IntoStream}; impl Extend for HashSet -where T: Eq + Hash, - H: BuildHasher + Default { +where + T: Eq + Hash, + H: BuildHasher + Default, +{ fn stream_extend<'a, S: IntoStream + 'a>( &'a mut self, stream: S, diff --git a/src/collections/hash_set/from_stream.rs b/src/collections/hash_set/from_stream.rs index 3714ae8e..42447fef 100644 --- a/src/collections/hash_set/from_stream.rs +++ b/src/collections/hash_set/from_stream.rs @@ -1,12 +1,14 @@ -use std::pin::Pin; -use std::hash::{Hash, BuildHasher}; use std::collections::HashSet; +use std::hash::{BuildHasher, Hash}; +use std::pin::Pin; use crate::stream::{Extend, FromStream, IntoStream}; impl FromStream for HashSet -where T: Eq + Hash, - H: BuildHasher + Default { +where + T: Eq + Hash, + H: BuildHasher + Default, +{ #[inline] fn from_stream<'a, S: IntoStream>( stream: S, diff --git a/src/collections/linked_list/extend.rs b/src/collections/linked_list/extend.rs index 8f825470..567a92d3 100644 --- a/src/collections/linked_list/extend.rs +++ b/src/collections/linked_list/extend.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::LinkedList; +use std::pin::Pin; use crate::prelude::*; use crate::stream::{Extend, IntoStream}; diff --git a/src/collections/linked_list/from_stream.rs b/src/collections/linked_list/from_stream.rs index 40b1100f..3ffe149b 100644 --- a/src/collections/linked_list/from_stream.rs +++ b/src/collections/linked_list/from_stream.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::LinkedList; +use std::pin::Pin; use crate::stream::{Extend, FromStream, IntoStream}; diff --git a/src/collections/mod.rs b/src/collections/mod.rs index 2ccdb23a..ae9efaa9 100644 --- a/src/collections/mod.rs +++ b/src/collections/mod.rs @@ -3,18 +3,18 @@ //! This library provides efficient implementations of the most common general purpose programming //! data structures. -pub mod vec_deque; -pub mod hash_map; -pub mod hash_set; +pub mod binary_heap; pub mod btree_map; pub mod btree_set; -pub mod binary_heap; +pub mod hash_map; +pub mod hash_set; pub mod linked_list; +pub mod vec_deque; -pub use vec_deque::VecDeque; -pub use hash_map::HashMap; -pub use hash_set::HashSet; +pub use binary_heap::BinaryHeap; pub use btree_map::BTreeMap; pub use btree_set::BTreeSet; -pub use binary_heap::BinaryHeap; +pub use hash_map::HashMap; +pub use hash_set::HashSet; pub use linked_list::LinkedList; +pub use vec_deque::VecDeque; diff --git a/src/collections/vec_deque/extend.rs b/src/collections/vec_deque/extend.rs index b8884d81..d034bdcd 100644 --- a/src/collections/vec_deque/extend.rs +++ b/src/collections/vec_deque/extend.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::VecDeque; +use std::pin::Pin; use crate::prelude::*; use crate::stream::{Extend, IntoStream}; diff --git a/src/collections/vec_deque/from_stream.rs b/src/collections/vec_deque/from_stream.rs index ef92a49c..8903de0e 100644 --- a/src/collections/vec_deque/from_stream.rs +++ b/src/collections/vec_deque/from_stream.rs @@ -1,5 +1,5 @@ -use std::pin::Pin; use std::collections::VecDeque; +use std::pin::Pin; use crate::stream::{Extend, FromStream, IntoStream}; diff --git a/src/vec/from_stream.rs b/src/vec/from_stream.rs index f4ca9a99..b326b04c 100644 --- a/src/vec/from_stream.rs +++ b/src/vec/from_stream.rs @@ -1,7 +1,7 @@ -use std::pin::Pin; use std::borrow::Cow; -use std::sync::Arc; +use std::pin::Pin; use std::rc::Rc; +use std::sync::Arc; use crate::stream::{Extend, FromStream, IntoStream};