Coverage Report

Created: 2026-02-26 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.13.0/src/inner/entry.rs
Line
Count
Source
1
use super::{equivalent, get_hash, Bucket, Core};
2
use crate::map::{Entry, IndexedEntry};
3
use crate::HashValue;
4
use core::cmp::Ordering;
5
use core::mem;
6
7
impl<'a, K, V> Entry<'a, K, V> {
8
0
    pub(crate) fn new(map: &'a mut Core<K, V>, hash: HashValue, key: K) -> Self
9
0
    where
10
0
        K: Eq,
11
    {
12
0
        let eq = equivalent(&key, &map.entries);
13
0
        match map.indices.find_entry(hash.get(), eq) {
14
0
            Ok(entry) => Entry::Occupied(OccupiedEntry {
15
0
                bucket: entry.bucket_index(),
16
0
                index: *entry.get(),
17
0
                map,
18
0
            }),
19
0
            Err(_) => Entry::Vacant(VacantEntry { map, hash, key }),
20
        }
21
0
    }
22
}
23
24
/// A view into an occupied entry in an [`IndexMap`][crate::IndexMap].
25
/// It is part of the [`Entry`] enum.
26
pub struct OccupiedEntry<'a, K, V> {
27
    map: &'a mut Core<K, V>,
28
    // We have a mutable reference to the map, which keeps these two
29
    // indices valid and pointing to the correct entry.
30
    index: usize,
31
    bucket: usize,
32
}
33
34
impl<'a, K, V> OccupiedEntry<'a, K, V> {
35
    /// Constructor for `RawEntryMut::from_hash`
36
0
    pub(crate) fn from_hash<F>(
37
0
        map: &'a mut Core<K, V>,
38
0
        hash: HashValue,
39
0
        mut is_match: F,
40
0
    ) -> Result<Self, &'a mut Core<K, V>>
41
0
    where
42
0
        F: FnMut(&K) -> bool,
43
    {
44
0
        let entries = &*map.entries;
45
0
        let eq = move |&i: &usize| is_match(&entries[i].key);
46
0
        match map.indices.find_entry(hash.get(), eq) {
47
0
            Ok(entry) => Ok(OccupiedEntry {
48
0
                bucket: entry.bucket_index(),
49
0
                index: *entry.get(),
50
0
                map,
51
0
            }),
52
0
            Err(_) => Err(map),
53
        }
54
0
    }
55
56
0
    pub(crate) fn into_core(self) -> &'a mut Core<K, V> {
57
0
        self.map
58
0
    }
59
60
0
    pub(crate) fn get_bucket(&self) -> &Bucket<K, V> {
61
0
        &self.map.entries[self.index]
62
0
    }
Unexecuted instantiation: <indexmap::inner::entry::OccupiedEntry<alloc::string::String, bson::bson::Bson>>::get_bucket
Unexecuted instantiation: <indexmap::inner::entry::OccupiedEntry<_, _>>::get_bucket
63
64
0
    pub(crate) fn get_bucket_mut(&mut self) -> &mut Bucket<K, V> {
65
0
        &mut self.map.entries[self.index]
66
0
    }
67
68
0
    pub(crate) fn into_bucket(self) -> &'a mut Bucket<K, V> {
69
0
        &mut self.map.entries[self.index]
70
0
    }
Unexecuted instantiation: <indexmap::inner::entry::OccupiedEntry<alloc::string::String, bson::bson::Bson>>::into_bucket
Unexecuted instantiation: <indexmap::inner::entry::OccupiedEntry<_, _>>::into_bucket
71
72
    /// Return the index of the key-value pair
73
    #[inline]
74
0
    pub fn index(&self) -> usize {
75
0
        self.index
76
0
    }
77
78
    /// Gets a reference to the entry's key in the map.
79
    ///
80
    /// Note that this is not the key that was used to find the entry. There may be an observable
81
    /// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
82
    /// extra fields or the memory address of an allocation.
83
0
    pub fn key(&self) -> &K {
84
0
        &self.get_bucket().key
85
0
    }
Unexecuted instantiation: <indexmap::inner::entry::OccupiedEntry<alloc::string::String, bson::bson::Bson>>::key
Unexecuted instantiation: <indexmap::inner::entry::OccupiedEntry<_, _>>::key
86
87
    /// Gets a reference to the entry's value in the map.
88
0
    pub fn get(&self) -> &V {
89
0
        &self.get_bucket().value
90
0
    }
91
92
    /// Gets a mutable reference to the entry's value in the map.
93
    ///
94
    /// If you need a reference which may outlive the destruction of the
95
    /// [`Entry`] value, see [`into_mut`][Self::into_mut].
96
0
    pub fn get_mut(&mut self) -> &mut V {
97
0
        &mut self.get_bucket_mut().value
98
0
    }
99
100
    /// Converts into a mutable reference to the entry's value in the map,
101
    /// with a lifetime bound to the map itself.
102
0
    pub fn into_mut(self) -> &'a mut V {
103
0
        &mut self.into_bucket().value
104
0
    }
Unexecuted instantiation: <indexmap::inner::entry::OccupiedEntry<alloc::string::String, bson::bson::Bson>>::into_mut
Unexecuted instantiation: <indexmap::inner::entry::OccupiedEntry<_, _>>::into_mut
105
106
    /// Sets the value of the entry to `value`, and returns the entry's old value.
107
0
    pub fn insert(&mut self, value: V) -> V {
108
0
        mem::replace(self.get_mut(), value)
109
0
    }
110
111
    /// Remove the key, value pair stored in the map for this entry, and return the value.
112
    ///
113
    /// **NOTE:** This is equivalent to [`.swap_remove()`][Self::swap_remove], replacing this
114
    /// entry's position with the last element, and it is deprecated in favor of calling that
115
    /// explicitly. If you need to preserve the relative order of the keys in the map, use
116
    /// [`.shift_remove()`][Self::shift_remove] instead.
117
    #[deprecated(note = "`remove` disrupts the map order -- \
118
        use `swap_remove` or `shift_remove` for explicit behavior.")]
119
0
    pub fn remove(self) -> V {
120
0
        self.swap_remove()
121
0
    }
122
123
    /// Remove the key, value pair stored in the map for this entry, and return the value.
124
    ///
125
    /// Like [`Vec::swap_remove`][alloc::vec::Vec::swap_remove], the pair is removed by swapping it
126
    /// with the last element of the map and popping it off.
127
    /// **This perturbs the position of what used to be the last element!**
128
    ///
129
    /// Computes in **O(1)** time (average).
130
0
    pub fn swap_remove(self) -> V {
131
0
        self.swap_remove_entry().1
132
0
    }
133
134
    /// Remove the key, value pair stored in the map for this entry, and return the value.
135
    ///
136
    /// Like [`Vec::remove`][alloc::vec::Vec::remove], the pair is removed by shifting all of the
137
    /// elements that follow it, preserving their relative order.
138
    /// **This perturbs the index of all of those elements!**
139
    ///
140
    /// Computes in **O(n)** time (average).
141
0
    pub fn shift_remove(self) -> V {
142
0
        self.shift_remove_entry().1
143
0
    }
144
145
    /// Remove and return the key, value pair stored in the map for this entry
146
    ///
147
    /// **NOTE:** This is equivalent to [`.swap_remove_entry()`][Self::swap_remove_entry],
148
    /// replacing this entry's position with the last element, and it is deprecated in favor of
149
    /// calling that explicitly. If you need to preserve the relative order of the keys in the map,
150
    /// use [`.shift_remove_entry()`][Self::shift_remove_entry] instead.
151
    #[deprecated(note = "`remove_entry` disrupts the map order -- \
152
        use `swap_remove_entry` or `shift_remove_entry` for explicit behavior.")]
153
0
    pub fn remove_entry(self) -> (K, V) {
154
0
        self.swap_remove_entry()
155
0
    }
156
157
    /// Remove and return the key, value pair stored in the map for this entry
158
    ///
159
    /// Like [`Vec::swap_remove`][alloc::vec::Vec::swap_remove], the pair is removed by swapping it
160
    /// with the last element of the map and popping it off.
161
    /// **This perturbs the position of what used to be the last element!**
162
    ///
163
    /// Computes in **O(1)** time (average).
164
0
    pub fn swap_remove_entry(mut self) -> (K, V) {
165
0
        self.remove_index();
166
0
        self.map.swap_remove_finish(self.index)
167
0
    }
168
169
    /// Remove and return the key, value pair stored in the map for this entry
170
    ///
171
    /// Like [`Vec::remove`][alloc::vec::Vec::remove], the pair is removed by shifting all of the
172
    /// elements that follow it, preserving their relative order.
173
    /// **This perturbs the index of all of those elements!**
174
    ///
175
    /// Computes in **O(n)** time (average).
176
0
    pub fn shift_remove_entry(mut self) -> (K, V) {
177
0
        self.remove_index();
178
0
        self.map.shift_remove_finish(self.index)
179
0
    }
180
181
0
    fn remove_index(&mut self) {
182
0
        let entry = self.map.indices.get_bucket_entry(self.bucket).unwrap();
183
0
        debug_assert_eq!(*entry.get(), self.index);
184
0
        entry.remove();
185
0
    }
186
187
    /// Moves the position of the entry to a new index
188
    /// by shifting all other entries in-between.
189
    ///
190
    /// This is equivalent to [`IndexMap::move_index`][`crate::IndexMap::move_index`]
191
    /// coming `from` the current [`.index()`][Self::index].
192
    ///
193
    /// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
194
    /// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
195
    ///
196
    /// ***Panics*** if `to` is out of bounds.
197
    ///
198
    /// Computes in **O(n)** time (average).
199
    #[track_caller]
200
0
    pub fn move_index(self, to: usize) {
201
0
        if self.index != to {
202
0
            let _ = self.map.entries[to]; // explicit bounds check
203
0
            self.map.move_index_inner(self.index, to);
204
0
            self.update_index(to);
205
0
        }
206
0
    }
207
208
    /// Swaps the position of entry with another.
209
    ///
210
    /// This is equivalent to [`IndexMap::swap_indices`][`crate::IndexMap::swap_indices`]
211
    /// with the current [`.index()`][Self::index] as one of the two being swapped.
212
    ///
213
    /// ***Panics*** if the `other` index is out of bounds.
214
    ///
215
    /// Computes in **O(1)** time (average).
216
    #[track_caller]
217
0
    pub fn swap_indices(self, other: usize) {
218
0
        if self.index != other {
219
            // Since we already know where our bucket is, we only need to find the other.
220
0
            let hash = self.map.entries[other].hash;
221
0
            let other_mut = self.map.indices.find_mut(hash.get(), move |&i| i == other);
222
0
            *other_mut.expect("index not found") = self.index;
223
224
0
            self.map.entries.swap(self.index, other);
225
0
            self.update_index(other);
226
0
        }
227
0
    }
228
229
0
    fn update_index(self, to: usize) {
230
0
        let index = self.map.indices.get_bucket_mut(self.bucket).unwrap();
231
0
        debug_assert_eq!(*index, self.index);
232
0
        *index = to;
233
0
    }
234
}
235
236
impl<'a, K, V> From<IndexedEntry<'a, K, V>> for OccupiedEntry<'a, K, V> {
237
0
    fn from(other: IndexedEntry<'a, K, V>) -> Self {
238
0
        let index = other.index();
239
0
        let map = other.into_core();
240
0
        let hash = map.entries[index].hash;
241
0
        let bucket = map
242
0
            .indices
243
0
            .find_bucket_index(hash.get(), move |&i| i == index)
244
0
            .expect("index not found");
245
0
        Self { map, index, bucket }
246
0
    }
247
}
248
249
/// A view into a vacant entry in an [`IndexMap`][crate::IndexMap].
250
/// It is part of the [`Entry`] enum.
251
pub struct VacantEntry<'a, K, V> {
252
    map: &'a mut Core<K, V>,
253
    hash: HashValue,
254
    key: K,
255
}
256
257
impl<'a, K, V> VacantEntry<'a, K, V> {
258
    /// Return the index where a key-value pair may be inserted.
259
0
    pub fn index(&self) -> usize {
260
0
        self.map.indices.len()
261
0
    }
262
263
    /// Gets a reference to the key that was used to find the entry.
264
0
    pub fn key(&self) -> &K {
265
0
        &self.key
266
0
    }
Unexecuted instantiation: <indexmap::inner::entry::VacantEntry<alloc::string::String, bson::bson::Bson>>::key
Unexecuted instantiation: <indexmap::inner::entry::VacantEntry<_, _>>::key
267
268
0
    pub(crate) fn key_mut(&mut self) -> &mut K {
269
0
        &mut self.key
270
0
    }
271
272
    /// Takes ownership of the key, leaving the entry vacant.
273
0
    pub fn into_key(self) -> K {
274
0
        self.key
275
0
    }
276
277
    /// Inserts the entry's key and the given value into the map, and returns a mutable reference
278
    /// to the value.
279
    ///
280
    /// Computes in **O(1)** time (amortized average).
281
0
    pub fn insert(self, value: V) -> &'a mut V {
282
0
        let Self { map, hash, key } = self;
283
0
        map.insert_unique(hash, key, value).value_mut()
284
0
    }
Unexecuted instantiation: <indexmap::inner::entry::VacantEntry<alloc::string::String, bson::bson::Bson>>::insert
Unexecuted instantiation: <indexmap::inner::entry::VacantEntry<_, _>>::insert
285
286
    /// Inserts the entry's key and the given value into the map, and returns an `OccupiedEntry`.
287
    ///
288
    /// Computes in **O(1)** time (amortized average).
289
0
    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
290
0
        let Self { map, hash, key } = self;
291
0
        let index = map.indices.len();
292
0
        debug_assert_eq!(index, map.entries.len());
293
0
        let bucket = map
294
0
            .indices
295
0
            .insert_unique(hash.get(), index, get_hash(&map.entries))
296
0
            .bucket_index();
297
0
        map.push_entry(hash, key, value);
298
0
        OccupiedEntry { map, index, bucket }
299
0
    }
300
301
    /// Inserts the entry's key and the given value into the map at its ordered
302
    /// position among sorted keys, and returns the new index and a mutable
303
    /// reference to the value.
304
    ///
305
    /// If the existing keys are **not** already sorted, then the insertion
306
    /// index is unspecified (like [`slice::binary_search`]), but the key-value
307
    /// pair is inserted at that position regardless.
308
    ///
309
    /// Computes in **O(n)** time (average).
310
0
    pub fn insert_sorted(self, value: V) -> (usize, &'a mut V)
311
0
    where
312
0
        K: Ord,
313
    {
314
0
        let slice = crate::map::Slice::from_slice(&self.map.entries);
315
0
        let i = slice.binary_search_keys(&self.key).unwrap_err();
316
0
        (i, self.shift_insert(i, value))
317
0
    }
318
319
    /// Inserts the entry's key and the given value into the map at its ordered
320
    /// position among keys sorted by `cmp`, and returns the new index and a
321
    /// mutable reference to the value.
322
    ///
323
    /// If the existing keys are **not** already sorted, then the insertion
324
    /// index is unspecified (like [`slice::binary_search`]), but the key-value
325
    /// pair is inserted at that position regardless.
326
    ///
327
    /// Computes in **O(n)** time (average).
328
0
    pub fn insert_sorted_by<F>(self, value: V, mut cmp: F) -> (usize, &'a mut V)
329
0
    where
330
0
        F: FnMut(&K, &V, &K, &V) -> Ordering,
331
    {
332
0
        let slice = crate::map::Slice::from_slice(&self.map.entries);
333
0
        let (Ok(i) | Err(i)) = slice.binary_search_by(|k, v| cmp(k, v, &self.key, &value));
334
0
        (i, self.shift_insert(i, value))
335
0
    }
336
337
    /// Inserts the entry's key and the given value into the map at its ordered
338
    /// position using a sort-key extraction function, and returns the new index
339
    /// and a mutable reference to the value.
340
    ///
341
    /// If the existing keys are **not** already sorted, then the insertion
342
    /// index is unspecified (like [`slice::binary_search`]), but the key-value
343
    /// pair is inserted at that position regardless.
344
    ///
345
    /// Computes in **O(n)** time (average).
346
0
    pub fn insert_sorted_by_key<B, F>(self, value: V, mut sort_key: F) -> (usize, &'a mut V)
347
0
    where
348
0
        B: Ord,
349
0
        F: FnMut(&K, &V) -> B,
350
    {
351
0
        let search_key = sort_key(&self.key, &value);
352
0
        let slice = crate::map::Slice::from_slice(&self.map.entries);
353
0
        let (Ok(i) | Err(i)) = slice.binary_search_by_key(&search_key, sort_key);
354
0
        (i, self.shift_insert(i, value))
355
0
    }
356
357
    /// Inserts the entry's key and the given value into the map at the given index,
358
    /// shifting others to the right, and returns a mutable reference to the value.
359
    ///
360
    /// ***Panics*** if `index` is out of bounds.
361
    ///
362
    /// Computes in **O(n)** time (average).
363
    #[track_caller]
364
0
    pub fn shift_insert(self, index: usize, value: V) -> &'a mut V {
365
0
        self.map
366
0
            .shift_insert_unique(index, self.hash, self.key, value)
367
0
            .value_mut()
368
0
    }
369
370
    /// Replaces the key at the given index with this entry's key, returning the
371
    /// old key and an `OccupiedEntry` for that index.
372
    ///
373
    /// ***Panics*** if `index` is out of bounds.
374
    ///
375
    /// Computes in **O(1)** time (average).
376
    #[track_caller]
377
0
    pub fn replace_index(self, index: usize) -> (K, OccupiedEntry<'a, K, V>) {
378
0
        let Self { map, hash, key } = self;
379
380
        // NB: This removal and insertion isn't "no grow" (with unreachable hasher)
381
        // because hashbrown's tombstones might force a resize anyway.
382
0
        let old_hash = map.entries[index].hash;
383
0
        map.indices
384
0
            .find_entry(old_hash.get(), move |&i| i == index)
385
0
            .expect("index not found")
386
0
            .remove();
387
0
        let bucket = map
388
0
            .indices
389
0
            .insert_unique(hash.get(), index, get_hash(&map.entries))
390
0
            .bucket_index();
391
392
0
        let entry = &mut map.entries[index];
393
0
        entry.hash = hash;
394
0
        let old_key = mem::replace(&mut entry.key, key);
395
396
0
        (old_key, OccupiedEntry { map, index, bucket })
397
0
    }
398
}