@@ -1285,6 +1285,39 @@ where
12851285 }
12861286 }
12871287
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+
12881321 /// Removes a key from the map, returning the value at the key if the key
12891322 /// was previously in the map.
12901323 ///
@@ -2394,6 +2427,40 @@ impl<K: Debug, V, S, A: Allocator + Clone> Debug for VacantEntry<'_, K, V, S, A>
23942427 }
23952428}
23962429
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+
23972464impl < ' a , K , V , S , A : Allocator + Clone > IntoIterator for & ' a HashMap < K , V , S , A > {
23982465 type Item = ( & ' a K , & ' a V ) ;
23992466 type IntoIter = Iter < ' a , K , V > ;
0 commit comments