@@ -1285,6 +1285,39 @@ where
1285
1285
}
1286
1286
}
1287
1287
1288
+ /// Tries to insert a key-value pair into the map, and returns
1289
+ /// a mutable reference to the value in the entry.
1290
+ ///
1291
+ /// If the map already had this key present, nothing is updated, and
1292
+ /// an error containing the occupied entry and the value is returned.
1293
+ ///
1294
+ /// # Examples
1295
+ ///
1296
+ /// Basic usage:
1297
+ ///
1298
+ /// ```
1299
+ /// use hashbrown::HashMap;
1300
+ ///
1301
+ /// let mut map = HashMap::new();
1302
+ /// assert_eq!(map.try_insert(37, "a").unwrap(), &"a");
1303
+ ///
1304
+ /// let err = map.try_insert(37, "b").unwrap_err();
1305
+ /// assert_eq!(err.entry.key(), &37);
1306
+ /// assert_eq!(err.entry.get(), &"a");
1307
+ /// assert_eq!(err.value, "b");
1308
+ /// ```
1309
+ #[ cfg_attr( feature = "inline-more" , inline) ]
1310
+ pub fn try_insert (
1311
+ & mut self ,
1312
+ key : K ,
1313
+ value : V ,
1314
+ ) -> Result < & mut V , OccupiedError < ' _ , K , V , S , A > > {
1315
+ match self . entry ( key) {
1316
+ Entry :: Occupied ( entry) => Err ( OccupiedError { entry, value } ) ,
1317
+ Entry :: Vacant ( entry) => Ok ( entry. insert ( value) ) ,
1318
+ }
1319
+ }
1320
+
1288
1321
/// Removes a key from the map, returning the value at the key if the key
1289
1322
/// was previously in the map.
1290
1323
///
@@ -2394,6 +2427,40 @@ impl<K: Debug, V, S, A: Allocator + Clone> Debug for VacantEntry<'_, K, V, S, A>
2394
2427
}
2395
2428
}
2396
2429
2430
+ /// The error returned by [`try_insert`](HashMap::try_insert) when the key already exists.
2431
+ ///
2432
+ /// Contains the occupied entry, and the value that was not inserted.
2433
+ pub struct OccupiedError < ' a , K , V , S , A : Allocator + Clone = Global > {
2434
+ /// The entry in the map that was already occupied.
2435
+ pub entry : OccupiedEntry < ' a , K , V , S , A > ,
2436
+ /// The value which was not inserted, because the entry was already occupied.
2437
+ pub value : V ,
2438
+ }
2439
+
2440
+ impl < K : Debug , V : Debug , S , A : Allocator + Clone > Debug for OccupiedError < ' _ , K , V , S , A > {
2441
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2442
+ f. debug_struct ( "OccupiedError" )
2443
+ . field ( "key" , self . entry . key ( ) )
2444
+ . field ( "old_value" , self . entry . get ( ) )
2445
+ . field ( "new_value" , & self . value )
2446
+ . finish ( )
2447
+ }
2448
+ }
2449
+
2450
+ impl < ' a , K : Debug , V : Debug , S , A : Allocator + Clone > fmt:: Display
2451
+ for OccupiedError < ' a , K , V , S , A >
2452
+ {
2453
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2454
+ write ! (
2455
+ f,
2456
+ "failed to insert {:?}, key {:?} already exists with value {:?}" ,
2457
+ self . value,
2458
+ self . entry. key( ) ,
2459
+ self . entry. get( ) ,
2460
+ )
2461
+ }
2462
+ }
2463
+
2397
2464
impl < ' a , K , V , S , A : Allocator + Clone > IntoIterator for & ' a HashMap < K , V , S , A > {
2398
2465
type Item = ( & ' a K , & ' a V ) ;
2399
2466
type IntoIter = Iter < ' a , K , V > ;
0 commit comments