|
| 1 | +// ignore-tidy-filelength |
| 2 | + |
1 | 3 | #[cfg(test)]
|
2 | 4 | mod tests;
|
3 | 5 |
|
@@ -842,6 +844,37 @@ where
|
842 | 844 | self.base.insert(k, v)
|
843 | 845 | }
|
844 | 846 |
|
| 847 | + /// Tries to insert a key-value pair into the map, and returns |
| 848 | + /// a mutable reference to the value in the entry. |
| 849 | + /// |
| 850 | + /// If the map already had this key present, nothing is updated, and |
| 851 | + /// an error containing the occupied entry and the value is returned. |
| 852 | + /// |
| 853 | + /// # Examples |
| 854 | + /// |
| 855 | + /// Basic usage: |
| 856 | + /// |
| 857 | + /// ``` |
| 858 | + /// #![feature(map_try_insert)] |
| 859 | + /// |
| 860 | + /// use std::collections::HashMap; |
| 861 | + /// |
| 862 | + /// let mut map = HashMap::new(); |
| 863 | + /// assert_eq!(map.try_insert(37, "a").unwrap(), &"a"); |
| 864 | + /// |
| 865 | + /// let err = map.try_insert(37, "b").unwrap_err(); |
| 866 | + /// assert_eq!(err.entry.key(), &37); |
| 867 | + /// assert_eq!(err.entry.get(), &"a"); |
| 868 | + /// assert_eq!(err.value, "b"); |
| 869 | + /// ``` |
| 870 | + #[unstable(feature = "map_try_insert", issue = "82766")] |
| 871 | + pub fn try_insert(&mut self, key: K, value: V) -> Result<&mut V, OccupiedError<'_, K, V>> { |
| 872 | + match self.entry(key) { |
| 873 | + Occupied(entry) => Err(OccupiedError { entry, value }), |
| 874 | + Vacant(entry) => Ok(entry.insert(value)), |
| 875 | + } |
| 876 | + } |
| 877 | + |
845 | 878 | /// Removes a key from the map, returning the value at the key if the key
|
846 | 879 | /// was previously in the map.
|
847 | 880 | ///
|
@@ -1851,6 +1884,41 @@ impl<K: Debug, V> Debug for VacantEntry<'_, K, V> {
|
1851 | 1884 | }
|
1852 | 1885 | }
|
1853 | 1886 |
|
| 1887 | +/// The error returned by [`try_insert`](HashMap::try_insert) when the key already exists. |
| 1888 | +/// |
| 1889 | +/// Contains the occupied entry, and the value that was not inserted. |
| 1890 | +#[unstable(feature = "map_try_insert", issue = "82766")] |
| 1891 | +pub struct OccupiedError<'a, K: 'a, V: 'a> { |
| 1892 | + /// The entry in the map that was already occupied. |
| 1893 | + pub entry: OccupiedEntry<'a, K, V>, |
| 1894 | + /// The value which was not inserted, because the entry was already occupied. |
| 1895 | + pub value: V, |
| 1896 | +} |
| 1897 | + |
| 1898 | +#[unstable(feature = "map_try_insert", issue = "82766")] |
| 1899 | +impl<K: Debug, V: Debug> Debug for OccupiedError<'_, K, V> { |
| 1900 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 1901 | + f.debug_struct("OccupiedError") |
| 1902 | + .field("key", self.entry.key()) |
| 1903 | + .field("old_value", self.entry.get()) |
| 1904 | + .field("new_value", &self.value) |
| 1905 | + .finish() |
| 1906 | + } |
| 1907 | +} |
| 1908 | + |
| 1909 | +#[unstable(feature = "map_try_insert", issue = "82766")] |
| 1910 | +impl<'a, K: Debug, V: Debug> fmt::Display for OccupiedError<'a, K, V> { |
| 1911 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 1912 | + write!( |
| 1913 | + f, |
| 1914 | + "failed to insert {:?}, key {:?} already exists with value {:?}", |
| 1915 | + self.value, |
| 1916 | + self.entry.key(), |
| 1917 | + self.entry.get(), |
| 1918 | + ) |
| 1919 | + } |
| 1920 | +} |
| 1921 | + |
1854 | 1922 | #[stable(feature = "rust1", since = "1.0.0")]
|
1855 | 1923 | impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S> {
|
1856 | 1924 | type Item = (&'a K, &'a V);
|
|
0 commit comments