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