Coverage Report

Created: 2025-07-02 06:18

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