summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2021-10-16 11:28:28 +0200
committerMatthias Beyer <mail@beyermatthias.de>2021-10-16 11:28:28 +0200
commitea0dfded03cf408d3d26deb446ce37c2e41299e9 (patch)
tree6c0324a310786396905bfab4801ce342aff99d7d
parent35cc78bef2c17e3906010a493f9d63462f7c7c39 (diff)
parente96e7911d90e495ff161cd32efe020e774b9200c (diff)
Merge branch 'no-pre-alloc-hm'HEADmaster
-rw-r--r--src/hashmap.rs60
1 files changed, 49 insertions, 11 deletions
diff --git a/src/hashmap.rs b/src/hashmap.rs
index 4095f15..6700087 100644
--- a/src/hashmap.rs
+++ b/src/hashmap.rs
@@ -12,6 +12,14 @@ use std::collections::HashMap;
use crate::error::Error;
+/// An iterator adapter to collect into a HashMap or error if the iterator yields a key twice
+///
+/// # Note
+///
+/// The FromIterator implementation for this type preallocates a hashmap using the
+/// Iterator::size_hint() function for the size of the hashmap.
+///
+/// For an adaptor that does not preallocate, have a look at `CollectOnceHashMapNoPrealloc`.
pub struct CollectOnceHashMap<K, V, S = std::collections::hash_map::RandomState>
where K: Eq + Hash + Debug
{
@@ -42,22 +50,52 @@ impl<K, V> FromIterator<(K, V)> for CollectOnceHashMap<K, V, std::collections::h
}
};
- let mut hm = HashMap::with_capacity(iter_size);
+ CollectOnceHashMap {
+ inner: collect_into_hm(HashMap::with_capacity(iter_size), iter)
+ }
+ }
+}
- for (element_key, element_value) in iter.into_iter() {
- if hm.contains_key(&element_key) {
- return CollectOnceHashMap {
- inner: Err(Error::DuplicatedKey(element_key))
- }
- } else {
- hm.insert(element_key, element_value);
- }
+/// See `CollectOnceHashMap`
+pub struct CollectOnceHashMapNoPrealloc<K, V, S = std::collections::hash_map::RandomState>
+ where K: Eq + Hash + Debug
+{
+ inner: std::result::Result<HashMap<K, V, S>, Error<K>>
+}
+
+impl<K, V, S> From<CollectOnceHashMapNoPrealloc<K, V, S>> for CollectOnceHashMap<K, V, S>
+ where K: Eq + Hash + Debug
+{
+ fn from(cohm: CollectOnceHashMapNoPrealloc<K, V, S>) -> Self {
+ CollectOnceHashMap { inner: cohm.inner }
+ }
+}
+
+impl<K, V> FromIterator<(K, V)> for CollectOnceHashMapNoPrealloc<K, V, std::collections::hash_map::RandomState>
+ where K: Eq + Hash + Debug
+{
+ fn from_iter<T>(iter: T) -> Self
+ where T: IntoIterator<Item = (K, V)>
+ {
+ CollectOnceHashMapNoPrealloc {
+ inner: collect_into_hm(HashMap::new(), iter)
}
+ }
+}
- CollectOnceHashMap {
- inner: Ok(hm)
+fn collect_into_hm<K, V, T>(mut hm: HashMap<K, V>, iter: T) -> std::result::Result<HashMap<K, V>, Error<K>>
+ where K: Eq + Hash + Debug,
+ T: IntoIterator<Item = (K, V)>
+{
+ for (element_key, element_value) in iter.into_iter() {
+ if hm.contains_key(&element_key) {
+ return Err(Error::DuplicatedKey(element_key))
+ } else {
+ hm.insert(element_key, element_value);
}
}
+
+ Ok(hm)
}