Coverage Report

Created: 2026-05-16 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.14.0/src/map/entry.rs
Line
Count
Source
1
use crate::Bucket;
2
use crate::inner::{Core, OccupiedEntry, VacantEntry};
3
use core::{fmt, mem};
4
5
/// Entry for an existing key-value pair in an [`IndexMap`][crate::IndexMap]
6
/// or a vacant location to insert one.
7
pub enum Entry<'a, K, V> {
8
    /// Existing slot with equivalent key.
9
    Occupied(OccupiedEntry<'a, K, V>),
10
    /// Vacant slot (no equivalent key in the map).
11
    Vacant(VacantEntry<'a, K, V>),
12
}
13
14
impl<'a, K, V> Entry<'a, K, V> {
15
    /// Return the index where the key-value pair exists or will be inserted.
16
    pub fn index(&self) -> usize {
17
        match self {
18
            Entry::Occupied(entry) => entry.index(),
19
            Entry::Vacant(entry) => entry.index(),
20
        }
21
    }
22
23
    /// Sets the value of the entry (after inserting if vacant), and returns an `OccupiedEntry`.
24
    ///
25
    /// Computes in **O(1)** time (amortized average).
26
    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
27
        match self {
28
            Entry::Occupied(mut entry) => {
29
                entry.insert(value);
30
                entry
31
            }
32
            Entry::Vacant(entry) => entry.insert_entry(value),
33
        }
34
    }
35
36
    /// Inserts the given default value in the entry if it is vacant and returns a mutable
37
    /// reference to it. Otherwise a mutable reference to an already existent value is returned.
38
    ///
39
    /// Computes in **O(1)** time (amortized average).
40
0
    pub fn or_insert(self, default: V) -> &'a mut V {
41
0
        match self {
42
0
            Entry::Occupied(entry) => entry.into_mut(),
43
0
            Entry::Vacant(entry) => entry.insert(default),
44
        }
45
0
    }
46
47
    /// Inserts the result of the `call` function in the entry if it is vacant and returns a mutable
48
    /// reference to it. Otherwise a mutable reference to an already existent value is returned.
49
    ///
50
    /// Computes in **O(1)** time (amortized average).
51
    pub fn or_insert_with<F>(self, call: F) -> &'a mut V
52
    where
53
        F: FnOnce() -> V,
54
    {
55
        match self {
56
            Entry::Occupied(entry) => entry.into_mut(),
57
            Entry::Vacant(entry) => entry.insert(call()),
58
        }
59
    }
60
61
    /// Inserts the result of the `call` function with a reference to the entry's key if it is
62
    /// vacant, and returns a mutable reference to the new value. Otherwise a mutable reference to
63
    /// an already existent value is returned.
64
    ///
65
    /// Computes in **O(1)** time (amortized average).
66
    pub fn or_insert_with_key<F>(self, call: F) -> &'a mut V
67
    where
68
        F: FnOnce(&K) -> V,
69
    {
70
        match self {
71
            Entry::Occupied(entry) => entry.into_mut(),
72
            Entry::Vacant(entry) => {
73
                let value = call(entry.key());
74
                entry.insert(value)
75
            }
76
        }
77
    }
78
79
    /// Gets a reference to the entry's key, either within the map if occupied,
80
    /// or else the new key that was used to find the entry.
81
    pub fn key(&self) -> &K {
82
        match *self {
83
            Entry::Occupied(ref entry) => entry.key(),
84
            Entry::Vacant(ref entry) => entry.key(),
85
        }
86
    }
87
88
    /// Modifies the entry if it is occupied.
89
    pub fn and_modify<F>(mut self, f: F) -> Self
90
    where
91
        F: FnOnce(&mut V),
92
    {
93
        if let Entry::Occupied(entry) = &mut self {
94
            f(entry.get_mut());
95
        }
96
        self
97
    }
98
99
    /// Inserts a default-constructed value in the entry if it is vacant and returns a mutable
100
    /// reference to it. Otherwise a mutable reference to an already existent value is returned.
101
    ///
102
    /// Computes in **O(1)** time (amortized average).
103
    pub fn or_default(self) -> &'a mut V
104
    where
105
        V: Default,
106
    {
107
        match self {
108
            Entry::Occupied(entry) => entry.into_mut(),
109
            Entry::Vacant(entry) => entry.insert(V::default()),
110
        }
111
    }
112
}
113
114
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Entry<'_, K, V> {
115
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116
        let mut tuple = f.debug_tuple("Entry");
117
        match self {
118
            Entry::Vacant(v) => tuple.field(v),
119
            Entry::Occupied(o) => tuple.field(o),
120
        };
121
        tuple.finish()
122
    }
123
}
124
125
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for OccupiedEntry<'_, K, V> {
126
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127
        f.debug_struct("OccupiedEntry")
128
            .field("key", self.key())
129
            .field("value", self.get())
130
            .finish()
131
    }
132
}
133
134
impl<K: fmt::Debug, V> fmt::Debug for VacantEntry<'_, K, V> {
135
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136
        f.debug_tuple("VacantEntry").field(self.key()).finish()
137
    }
138
}
139
140
/// A view into an occupied entry in an [`IndexMap`][crate::IndexMap] obtained by index.
141
///
142
/// This `struct` is created from the [`get_index_entry`][crate::IndexMap::get_index_entry] method.
143
pub struct IndexedEntry<'a, K, V> {
144
    map: &'a mut Core<K, V>,
145
    // We have a mutable reference to the map, which keeps the index
146
    // valid and pointing to the correct entry.
147
    index: usize,
148
}
149
150
impl<'a, K, V> IndexedEntry<'a, K, V> {
151
    pub(crate) fn new(map: &'a mut Core<K, V>, index: usize) -> Option<Self> {
152
        if index < map.len() {
153
            Some(Self { map, index })
154
        } else {
155
            None
156
        }
157
    }
158
159
    /// Return the index of the key-value pair
160
    #[inline]
161
    pub fn index(&self) -> usize {
162
        self.index
163
    }
164
165
    pub(crate) fn into_core(self) -> &'a mut Core<K, V> {
166
        self.map
167
    }
168
169
    fn get_bucket(&self) -> &Bucket<K, V> {
170
        &self.map.as_entries()[self.index]
171
    }
172
173
    fn get_bucket_mut(&mut self) -> &mut Bucket<K, V> {
174
        &mut self.map.as_entries_mut()[self.index]
175
    }
176
177
    fn into_bucket(self) -> &'a mut Bucket<K, V> {
178
        &mut self.map.as_entries_mut()[self.index]
179
    }
180
181
    /// Gets a reference to the entry's key in the map.
182
    pub fn key(&self) -> &K {
183
        &self.get_bucket().key
184
    }
185
186
    pub(super) fn key_mut(&mut self) -> &mut K {
187
        &mut self.get_bucket_mut().key
188
    }
189
190
    /// Gets a reference to the entry's value in the map.
191
    pub fn get(&self) -> &V {
192
        &self.get_bucket().value
193
    }
194
195
    /// Gets a mutable reference to the entry's value in the map.
196
    ///
197
    /// If you need a reference which may outlive the destruction of the
198
    /// `IndexedEntry` value, see [`into_mut`][Self::into_mut].
199
    pub fn get_mut(&mut self) -> &mut V {
200
        &mut self.get_bucket_mut().value
201
    }
202
203
    /// Sets the value of the entry to `value`, and returns the entry's old value.
204
    pub fn insert(&mut self, value: V) -> V {
205
        mem::replace(self.get_mut(), value)
206
    }
207
208
    /// Converts into a mutable reference to the entry's value in the map,
209
    /// with a lifetime bound to the map itself.
210
    pub fn into_mut(self) -> &'a mut V {
211
        &mut self.into_bucket().value
212
    }
213
214
    /// Remove and return the key, value pair stored in the map for this entry
215
    ///
216
    /// Like [`Vec::swap_remove`][alloc::vec::Vec::swap_remove], the pair is removed by swapping it
217
    /// with the last element of the map and popping it off.
218
    /// **This perturbs the position of what used to be the last element!**
219
    ///
220
    /// Computes in **O(1)** time (average).
221
    pub fn swap_remove_entry(self) -> (K, V) {
222
        self.map.swap_remove_index(self.index).unwrap()
223
    }
224
225
    /// Remove and return the key, value pair stored in the map for this entry
226
    ///
227
    /// Like [`Vec::remove`][alloc::vec::Vec::remove], the pair is removed by shifting all of the
228
    /// elements that follow it, preserving their relative order.
229
    /// **This perturbs the index of all of those elements!**
230
    ///
231
    /// Computes in **O(n)** time (average).
232
    pub fn shift_remove_entry(self) -> (K, V) {
233
        self.map.shift_remove_index(self.index).unwrap()
234
    }
235
236
    /// Remove the key, value pair stored in the map for this entry, and return the value.
237
    ///
238
    /// Like [`Vec::swap_remove`][alloc::vec::Vec::swap_remove], the pair is removed by swapping it
239
    /// with the last element of the map and popping it off.
240
    /// **This perturbs the position of what used to be the last element!**
241
    ///
242
    /// Computes in **O(1)** time (average).
243
    pub fn swap_remove(self) -> V {
244
        self.swap_remove_entry().1
245
    }
246
247
    /// Remove the key, value pair stored in the map for this entry, and return the value.
248
    ///
249
    /// Like [`Vec::remove`][alloc::vec::Vec::remove], the pair is removed by shifting all of the
250
    /// elements that follow it, preserving their relative order.
251
    /// **This perturbs the index of all of those elements!**
252
    ///
253
    /// Computes in **O(n)** time (average).
254
    pub fn shift_remove(self) -> V {
255
        self.shift_remove_entry().1
256
    }
257
258
    /// Moves the position of the entry to a new index
259
    /// by shifting all other entries in-between.
260
    ///
261
    /// This is equivalent to [`IndexMap::move_index`][`crate::IndexMap::move_index`]
262
    /// coming `from` the current [`.index()`][Self::index].
263
    ///
264
    /// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
265
    /// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
266
    ///
267
    /// ***Panics*** if `to` is out of bounds.
268
    ///
269
    /// Computes in **O(n)** time (average).
270
    #[track_caller]
271
    pub fn move_index(self, to: usize) {
272
        self.map.move_index(self.index, to);
273
    }
274
275
    /// Swaps the position of entry with another.
276
    ///
277
    /// This is equivalent to [`IndexMap::swap_indices`][`crate::IndexMap::swap_indices`]
278
    /// with the current [`.index()`][Self::index] as one of the two being swapped.
279
    ///
280
    /// ***Panics*** if the `other` index is out of bounds.
281
    ///
282
    /// Computes in **O(1)** time (average).
283
    #[track_caller]
284
    pub fn swap_indices(self, other: usize) {
285
        self.map.swap_indices(self.index, other);
286
    }
287
}
288
289
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IndexedEntry<'_, K, V> {
290
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
291
        f.debug_struct("IndexedEntry")
292
            .field("index", &self.index)
293
            .field("key", self.key())
294
            .field("value", self.get())
295
            .finish()
296
    }
297
}
298
299
impl<'a, K, V> From<OccupiedEntry<'a, K, V>> for IndexedEntry<'a, K, V> {
300
    fn from(other: OccupiedEntry<'a, K, V>) -> Self {
301
        Self {
302
            index: other.index(),
303
            map: other.into_core(),
304
        }
305
    }
306
}
307
308
#[test]
309
fn assert_send_sync() {
310
    fn assert_send_sync<T: Send + Sync>() {}
311
    assert_send_sync::<Entry<'_, i32, i32>>();
312
    assert_send_sync::<IndexedEntry<'_, i32, i32>>();
313
}