/rust/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.12.0/src/lib.rs
Line | Count | Source |
1 | | #![no_std] |
2 | | |
3 | | //! [`IndexMap`] is a hash table where the iteration order of the key-value |
4 | | //! pairs is independent of the hash values of the keys. |
5 | | //! |
6 | | //! [`IndexSet`] is a corresponding hash set using the same implementation and |
7 | | //! with similar properties. |
8 | | //! |
9 | | //! ### Highlights |
10 | | //! |
11 | | //! [`IndexMap`] and [`IndexSet`] are drop-in compatible with the std `HashMap` |
12 | | //! and `HashSet`, but they also have some features of note: |
13 | | //! |
14 | | //! - The ordering semantics (see their documentation for details) |
15 | | //! - Sorting methods and the [`.pop()`][IndexMap::pop] methods. |
16 | | //! - The [`Equivalent`] trait, which offers more flexible equality definitions |
17 | | //! between borrowed and owned versions of keys. |
18 | | //! - The [`MutableKeys`][map::MutableKeys] trait, which gives opt-in mutable |
19 | | //! access to map keys, and [`MutableValues`][set::MutableValues] for sets. |
20 | | //! |
21 | | //! ### Feature Flags |
22 | | //! |
23 | | //! To reduce the amount of compiled code in the crate by default, certain |
24 | | //! features are gated behind [feature flags]. These allow you to opt in to (or |
25 | | //! out of) functionality. Below is a list of the features available in this |
26 | | //! crate. |
27 | | //! |
28 | | //! * `std`: Enables features which require the Rust standard library. For more |
29 | | //! information see the section on [`no_std`]. |
30 | | //! * `rayon`: Enables parallel iteration and other parallel methods. |
31 | | //! * `serde`: Adds implementations for [`Serialize`] and [`Deserialize`] |
32 | | //! to [`IndexMap`] and [`IndexSet`]. Alternative implementations for |
33 | | //! (de)serializing [`IndexMap`] as an ordered sequence are available in the |
34 | | //! [`map::serde_seq`] module. |
35 | | //! * `arbitrary`: Adds implementations for the [`arbitrary::Arbitrary`] trait |
36 | | //! to [`IndexMap`] and [`IndexSet`]. |
37 | | //! * `quickcheck`: Adds implementations for the [`quickcheck::Arbitrary`] trait |
38 | | //! to [`IndexMap`] and [`IndexSet`]. |
39 | | //! * `borsh` (**deprecated**): Adds implementations for [`BorshSerialize`] and |
40 | | //! [`BorshDeserialize`] to [`IndexMap`] and [`IndexSet`]. Due to a cyclic |
41 | | //! dependency that arose between [`borsh`] and `indexmap`, `borsh v1.5.6` |
42 | | //! added an `indexmap` feature that should be used instead of enabling the |
43 | | //! feature here. |
44 | | //! |
45 | | //! _Note: only the `std` feature is enabled by default._ |
46 | | //! |
47 | | //! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section |
48 | | //! [`no_std`]: #no-standard-library-targets |
49 | | //! [`Serialize`]: `::serde_core::Serialize` |
50 | | //! [`Deserialize`]: `::serde_core::Deserialize` |
51 | | //! [`BorshSerialize`]: `::borsh::BorshSerialize` |
52 | | //! [`BorshDeserialize`]: `::borsh::BorshDeserialize` |
53 | | //! [`borsh`]: `::borsh` |
54 | | //! [`arbitrary::Arbitrary`]: `::arbitrary::Arbitrary` |
55 | | //! [`quickcheck::Arbitrary`]: `::quickcheck::Arbitrary` |
56 | | //! |
57 | | //! ### Alternate Hashers |
58 | | //! |
59 | | //! [`IndexMap`] and [`IndexSet`] have a default hasher type |
60 | | //! [`S = RandomState`][std::hash::RandomState], |
61 | | //! just like the standard `HashMap` and `HashSet`, which is resistant to |
62 | | //! HashDoS attacks but not the most performant. Type aliases can make it easier |
63 | | //! to use alternate hashers: |
64 | | //! |
65 | | //! ``` |
66 | | //! use fnv::FnvBuildHasher; |
67 | | //! use indexmap::{IndexMap, IndexSet}; |
68 | | //! |
69 | | //! type FnvIndexMap<K, V> = IndexMap<K, V, FnvBuildHasher>; |
70 | | //! type FnvIndexSet<T> = IndexSet<T, FnvBuildHasher>; |
71 | | //! |
72 | | //! let std: IndexSet<i32> = (0..100).collect(); |
73 | | //! let fnv: FnvIndexSet<i32> = (0..100).collect(); |
74 | | //! assert_eq!(std, fnv); |
75 | | //! ``` |
76 | | //! |
77 | | //! ### Rust Version |
78 | | //! |
79 | | //! This version of indexmap requires Rust 1.82 or later. |
80 | | //! |
81 | | //! The indexmap 2.x release series will use a carefully considered version |
82 | | //! upgrade policy, where in a later 2.x version, we will raise the minimum |
83 | | //! required Rust version. |
84 | | //! |
85 | | //! ## No Standard Library Targets |
86 | | //! |
87 | | //! This crate supports being built without `std`, requiring `alloc` instead. |
88 | | //! This is chosen by disabling the default "std" cargo feature, by adding |
89 | | //! `default-features = false` to your dependency specification. |
90 | | //! |
91 | | //! - Creating maps and sets using [`new`][IndexMap::new] and |
92 | | //! [`with_capacity`][IndexMap::with_capacity] is unavailable without `std`. |
93 | | //! Use methods [`IndexMap::default`], [`with_hasher`][IndexMap::with_hasher], |
94 | | //! [`with_capacity_and_hasher`][IndexMap::with_capacity_and_hasher] instead. |
95 | | //! A no-std compatible hasher will be needed as well, for example |
96 | | //! from the crate `twox-hash`. |
97 | | //! - Macros [`indexmap!`] and [`indexset!`] are unavailable without `std`. Use |
98 | | //! the macros [`indexmap_with_default!`] and [`indexset_with_default!`] instead. |
99 | | |
100 | | #![cfg_attr(docsrs, feature(doc_cfg))] |
101 | | |
102 | | extern crate alloc; |
103 | | |
104 | | #[cfg(feature = "std")] |
105 | | #[macro_use] |
106 | | extern crate std; |
107 | | |
108 | | mod arbitrary; |
109 | | #[macro_use] |
110 | | mod macros; |
111 | | #[cfg(feature = "borsh")] |
112 | | mod borsh; |
113 | | #[cfg(feature = "serde")] |
114 | | mod serde; |
115 | | #[cfg(feature = "sval")] |
116 | | mod sval; |
117 | | mod util; |
118 | | |
119 | | pub mod map; |
120 | | pub mod set; |
121 | | |
122 | | // Placed after `map` and `set` so new `rayon` methods on the types |
123 | | // are documented after the "normal" methods. |
124 | | #[cfg(feature = "rayon")] |
125 | | mod rayon; |
126 | | |
127 | | pub use crate::map::IndexMap; |
128 | | pub use crate::set::IndexSet; |
129 | | pub use equivalent::Equivalent; |
130 | | |
131 | | // shared private items |
132 | | |
133 | | /// Hash value newtype. Not larger than usize, since anything larger |
134 | | /// isn't used for selecting position anyway. |
135 | | #[derive(Clone, Copy, Debug, PartialEq)] |
136 | | struct HashValue(usize); |
137 | | |
138 | | impl HashValue { |
139 | | #[inline(always)] |
140 | 714k | fn get(self) -> u64 { |
141 | 714k | self.0 as u64 |
142 | 714k | } |
143 | | } |
144 | | |
145 | | #[derive(Copy, Debug)] |
146 | | struct Bucket<K, V> { |
147 | | hash: HashValue, |
148 | | key: K, |
149 | | value: V, |
150 | | } |
151 | | |
152 | | impl<K, V> Clone for Bucket<K, V> |
153 | | where |
154 | | K: Clone, |
155 | | V: Clone, |
156 | | { |
157 | | fn clone(&self) -> Self { |
158 | | Bucket { |
159 | | hash: self.hash, |
160 | | key: self.key.clone(), |
161 | | value: self.value.clone(), |
162 | | } |
163 | | } |
164 | | |
165 | | fn clone_from(&mut self, other: &Self) { |
166 | | self.hash = other.hash; |
167 | | self.key.clone_from(&other.key); |
168 | | self.value.clone_from(&other.value); |
169 | | } |
170 | | } |
171 | | |
172 | | impl<K, V> Bucket<K, V> { |
173 | | // field accessors -- used for `f` instead of closures in `.map(f)` |
174 | 475M | fn key_ref(&self) -> &K { |
175 | 475M | &self.key |
176 | 475M | } Unexecuted instantiation: <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Expression>, alloc::string::String>>::key_ref <indexmap::Bucket<naga::ir::Type, ()>>::key_ref Line | Count | Source | 174 | 475M | fn key_ref(&self) -> &K { | 175 | 475M | &self.key | 176 | 475M | } |
<indexmap::Bucket<naga::front::wgsl::parse::ast::Dependency, ()>>::key_ref Line | Count | Source | 174 | 163 | fn key_ref(&self) -> &K { | 175 | 163 | &self.key | 176 | 163 | } |
|
177 | 0 | fn value_ref(&self) -> &V { |
178 | 0 | &self.value |
179 | 0 | } |
180 | 1 | fn value_mut(&mut self) -> &mut V { |
181 | 1 | &mut self.value |
182 | 1 | } |
183 | 113 | fn key(self) -> K { |
184 | 113 | self.key |
185 | 113 | } |
186 | | fn value(self) -> V { |
187 | | self.value |
188 | | } |
189 | 72.3k | fn key_value(self) -> (K, V) { |
190 | 72.3k | (self.key, self.value) |
191 | 72.3k | } <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Expression>, alloc::string::String>>::key_value Line | Count | Source | 189 | 36.1k | fn key_value(self) -> (K, V) { | 190 | 36.1k | (self.key, self.value) | 191 | 36.1k | } |
<indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Expression>, (alloc::string::String, naga::span::Span)>>::key_value Line | Count | Source | 189 | 36.1k | fn key_value(self) -> (K, V) { | 190 | 36.1k | (self.key, self.value) | 191 | 36.1k | } |
Unexecuted instantiation: <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::GlobalVariable>, alloc::vec::Vec<alloc::string::String>>>::key_value Unexecuted instantiation: <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Type>, alloc::vec::Vec<alloc::string::String>>>::key_value Unexecuted instantiation: <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Constant>, alloc::vec::Vec<alloc::string::String>>>::key_value Unexecuted instantiation: <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Function>, alloc::vec::Vec<alloc::string::String>>>::key_value Unexecuted instantiation: <indexmap::Bucket<naga::diagnostic_filter::FilterableTriggeringRule, (naga::diagnostic_filter::Severity, naga::span::Span)>>::key_value Unexecuted instantiation: <indexmap::Bucket<(naga::arena::handle::Handle<naga::ir::Type>, usize), alloc::vec::Vec<alloc::string::String>>>::key_value |
192 | 36.1k | fn refs(&self) -> (&K, &V) { |
193 | 36.1k | (&self.key, &self.value) |
194 | 36.1k | } <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Expression>, alloc::string::String>>::refs Line | Count | Source | 192 | 36.1k | fn refs(&self) -> (&K, &V) { | 193 | 36.1k | (&self.key, &self.value) | 194 | 36.1k | } |
Unexecuted instantiation: <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::GlobalVariable>, alloc::vec::Vec<alloc::string::String>>>::refs Unexecuted instantiation: <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Type>, alloc::vec::Vec<alloc::string::String>>>::refs Unexecuted instantiation: <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Constant>, alloc::vec::Vec<alloc::string::String>>>::refs Unexecuted instantiation: <indexmap::Bucket<naga::arena::handle::Handle<naga::ir::Function>, alloc::vec::Vec<alloc::string::String>>>::refs Unexecuted instantiation: <indexmap::Bucket<naga::diagnostic_filter::FilterableTriggeringRule, (naga::diagnostic_filter::Severity, naga::span::Span)>>::refs <indexmap::Bucket<naga::ir::PredeclaredType, naga::arena::handle::Handle<naga::ir::Type>>>::refs Line | Count | Source | 192 | 1 | fn refs(&self) -> (&K, &V) { | 193 | 1 | (&self.key, &self.value) | 194 | 1 | } |
Unexecuted instantiation: <indexmap::Bucket<(naga::arena::handle::Handle<naga::ir::Type>, usize), alloc::vec::Vec<alloc::string::String>>>::refs Unexecuted instantiation: <indexmap::Bucket<usize, alloc::vec::Vec<alloc::string::String>>>::refs Unexecuted instantiation: <indexmap::Bucket<u32, alloc::vec::Vec<(u32, petgraph::graphmap::CompactDirection)>>>::refs |
195 | | fn ref_mut(&mut self) -> (&K, &mut V) { |
196 | | (&self.key, &mut self.value) |
197 | | } |
198 | | fn muts(&mut self) -> (&mut K, &mut V) { |
199 | | (&mut self.key, &mut self.value) |
200 | | } |
201 | | } |
202 | | |
203 | | /// The error type for [`try_reserve`][IndexMap::try_reserve] methods. |
204 | | #[derive(Clone, PartialEq, Eq, Debug)] |
205 | | pub struct TryReserveError { |
206 | | kind: TryReserveErrorKind, |
207 | | } |
208 | | |
209 | | #[derive(Clone, PartialEq, Eq, Debug)] |
210 | | enum TryReserveErrorKind { |
211 | | // The standard library's kind is currently opaque to us, otherwise we could unify this. |
212 | | Std(alloc::collections::TryReserveError), |
213 | | CapacityOverflow, |
214 | | AllocError { layout: alloc::alloc::Layout }, |
215 | | } |
216 | | |
217 | | // These are not `From` so we don't expose them in our public API. |
218 | | impl TryReserveError { |
219 | | fn from_alloc(error: alloc::collections::TryReserveError) -> Self { |
220 | | Self { |
221 | | kind: TryReserveErrorKind::Std(error), |
222 | | } |
223 | | } |
224 | | |
225 | | fn from_hashbrown(error: hashbrown::TryReserveError) -> Self { |
226 | | Self { |
227 | | kind: match error { |
228 | | hashbrown::TryReserveError::CapacityOverflow => { |
229 | | TryReserveErrorKind::CapacityOverflow |
230 | | } |
231 | | hashbrown::TryReserveError::AllocError { layout } => { |
232 | | TryReserveErrorKind::AllocError { layout } |
233 | | } |
234 | | }, |
235 | | } |
236 | | } |
237 | | } |
238 | | |
239 | | impl core::fmt::Display for TryReserveError { |
240 | | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
241 | | let reason = match &self.kind { |
242 | | TryReserveErrorKind::Std(e) => return core::fmt::Display::fmt(e, f), |
243 | | TryReserveErrorKind::CapacityOverflow => { |
244 | | " because the computed capacity exceeded the collection's maximum" |
245 | | } |
246 | | TryReserveErrorKind::AllocError { .. } => { |
247 | | " because the memory allocator returned an error" |
248 | | } |
249 | | }; |
250 | | f.write_str("memory allocation failed")?; |
251 | | f.write_str(reason) |
252 | | } |
253 | | } |
254 | | |
255 | | impl core::error::Error for TryReserveError {} |
256 | | |
257 | | // NOTE: This is copied from the slice module in the std lib. |
258 | | /// The error type returned by [`get_disjoint_indices_mut`][`IndexMap::get_disjoint_indices_mut`]. |
259 | | /// |
260 | | /// It indicates one of two possible errors: |
261 | | /// - An index is out-of-bounds. |
262 | | /// - The same index appeared multiple times in the array. |
263 | | // (or different but overlapping indices when ranges are provided) |
264 | | #[derive(Debug, Clone, PartialEq, Eq)] |
265 | | pub enum GetDisjointMutError { |
266 | | /// An index provided was out-of-bounds for the slice. |
267 | | IndexOutOfBounds, |
268 | | /// Two indices provided were overlapping. |
269 | | OverlappingIndices, |
270 | | } |
271 | | |
272 | | impl core::fmt::Display for GetDisjointMutError { |
273 | | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
274 | | let msg = match self { |
275 | | GetDisjointMutError::IndexOutOfBounds => "an index is out of bounds", |
276 | | GetDisjointMutError::OverlappingIndices => "there were overlapping indices", |
277 | | }; |
278 | | |
279 | | core::fmt::Display::fmt(msg, f) |
280 | | } |
281 | | } |
282 | | |
283 | | impl core::error::Error for GetDisjointMutError {} |