collect_with/
extend.rs

1use alloc::{
2  collections::{BinaryHeap, VecDeque},
3  string::String,
4  vec::Vec,
5};
6
7/// A trait for collections that can be pre-allocated with specific capacity and
8/// extended with elements.
9///
10/// This extends the standard [`Extend`] trait to provide a uniform interface
11/// for collection types that support capacity pre-allocation.
12///
13/// Pre-allocating capacity can improve performance when the number of elements
14/// is known in advance.
15/// Due to the fact that in Rust iterators, [size_hint()](Iterator::size_hint)
16/// might return `(0, None)`, pre-allocating capacity can be particularly
17/// useful.
18///
19/// # Implementors
20/// - alloc collections: `Vec<T>`, `String`, `VecDeque<T>`, `BinaryHeap<T>`
21/// - std types (with `std` feature): `OsString`, `HashMap`, `HashSet`,
22///   `PathBuf`
23/// - AHash collections (with `ahash` & `std` features): `AHashMap`, `AHashSet`
24pub trait ExtendWithCapacity<T>: Extend<T> {
25  fn with_capacity(capacity: usize) -> Self;
26}
27// ----------
28
29impl<T> ExtendWithCapacity<T> for Vec<T> {
30  fn with_capacity(capacity: usize) -> Self {
31    Vec::with_capacity(capacity)
32  }
33}
34
35impl<T> ExtendWithCapacity<T> for String
36where
37  String: Extend<T>,
38{
39  fn with_capacity(capacity: usize) -> Self {
40    String::with_capacity(capacity)
41  }
42}
43
44impl<T> ExtendWithCapacity<T> for VecDeque<T> {
45  fn with_capacity(capacity: usize) -> Self {
46    VecDeque::with_capacity(capacity)
47  }
48}
49
50impl<T: Ord> ExtendWithCapacity<T> for BinaryHeap<T> {
51  fn with_capacity(capacity: usize) -> Self {
52    BinaryHeap::with_capacity(capacity)
53  }
54}
55
56// OsString
57
58#[cfg(feature = "std")]
59impl<T> ExtendWithCapacity<T> for std::ffi::OsString
60where
61  std::ffi::OsString: Extend<T>,
62{
63  fn with_capacity(capacity: usize) -> Self {
64    std::ffi::OsString::with_capacity(capacity)
65  }
66}
67
68// Hash{Map, Set}
69
70#[cfg(feature = "std")]
71impl<K, V, S> ExtendWithCapacity<(K, V)> for std::collections::HashMap<K, V, S>
72where
73  K: Eq + core::hash::Hash,
74  S: core::hash::BuildHasher + Default,
75{
76  fn with_capacity(capacity: usize) -> Self {
77    std::collections::HashMap::with_capacity_and_hasher(capacity, S::default())
78  }
79}
80#[cfg(feature = "std")]
81impl<K, S> ExtendWithCapacity<K> for std::collections::HashSet<K, S>
82where
83  K: Eq + core::hash::Hash,
84  S: core::hash::BuildHasher + Default,
85{
86  fn with_capacity(capacity: usize) -> Self {
87    std::collections::HashSet::with_capacity_and_hasher(capacity, S::default())
88  }
89}
90
91// ahash{map, set}
92
93#[cfg(feature = "ahash")]
94impl<K: Eq + core::hash::Hash, V> ExtendWithCapacity<(K, V)>
95  for ahash::AHashMap<K, V>
96{
97  fn with_capacity(capacity: usize) -> Self {
98    ahash::AHashMap::with_capacity(capacity)
99  }
100}
101#[cfg(feature = "ahash")]
102impl<K: Eq + core::hash::Hash> ExtendWithCapacity<K> for ahash::AHashSet<K> {
103  fn with_capacity(capacity: usize) -> Self {
104    ahash::AHashSet::with_capacity(capacity)
105  }
106}
107
108// PathBuf
109
110#[cfg(feature = "std")]
111impl<T: AsRef<std::path::Path>> ExtendWithCapacity<T> for std::path::PathBuf {
112  fn with_capacity(capacity: usize) -> Self {
113    std::path::PathBuf::with_capacity(capacity)
114  }
115}
116
117// index{map, set}
118
119#[cfg(feature = "indexmap")]
120impl<K, V, S> ExtendWithCapacity<(K, V)> for indexmap::IndexMap<K, V, S>
121where
122  K: Eq + core::hash::Hash,
123  S: core::hash::BuildHasher + Default,
124{
125  fn with_capacity(capacity: usize) -> Self {
126    indexmap::IndexMap::with_capacity_and_hasher(capacity, S::default())
127  }
128}
129
130#[cfg(feature = "indexmap")]
131impl<K, S> ExtendWithCapacity<K> for indexmap::IndexSet<K, S>
132where
133  K: Eq + core::hash::Hash,
134  S: core::hash::BuildHasher + Default,
135{
136  fn with_capacity(capacity: usize) -> Self {
137    indexmap::IndexSet::with_capacity_and_hasher(capacity, S::default())
138  }
139}