@@ -386,6 +386,182 @@ pub enum Entry<'a, K, V, const N: usize> {
386386 Vacant ( VacantEntry < ' a , K , V , N > ) ,
387387}
388388
389+ impl < ' a , K , V , const N : usize > Entry < ' a , K , V , N >
390+ where
391+ K : Eq + Hash ,
392+ {
393+ /// Ensures a value is in the entry by inserting the default if empty, and
394+ /// returns a mutable reference to the value in the entry.
395+ ///
396+ /// # Examples
397+ ///
398+ /// ```
399+ /// use heapless::FnvIndexMap;
400+ ///
401+ /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
402+ /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
403+ /// let result = book_reviews
404+ /// .entry("Adventures of Huckleberry Finn")
405+ /// .or_insert("My favorite book.");
406+ ///
407+ /// assert_eq!(result, Ok(&mut "My favorite book."));
408+ /// assert_eq!(
409+ /// book_reviews["Adventures of Huckleberry Finn"],
410+ /// "My favorite book."
411+ /// );
412+ /// ```
413+ pub fn or_insert ( self , default : V ) -> Result < & ' a mut V , V > {
414+ match self {
415+ Self :: Occupied ( entry) => Ok ( entry. into_mut ( ) ) ,
416+ Self :: Vacant ( entry) => entry. insert ( default) ,
417+ }
418+ }
419+
420+ /// Ensures a value is in the entry by inserting the result of the default
421+ /// function if empty, and returns a mutable reference to the value in the
422+ /// entry.
423+ ///
424+ /// # Examples
425+ ///
426+ /// ```
427+ /// use heapless::FnvIndexMap;
428+ ///
429+ /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
430+ /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
431+ /// let s = "Masterpiece.".to_string();
432+ ///
433+ /// book_reviews
434+ /// .entry("Grimms' Fairy Tales")
435+ /// .or_insert_with(|| s);
436+ ///
437+ /// assert_eq!(
438+ /// book_reviews["Grimms' Fairy Tales"],
439+ /// "Masterpiece.".to_string()
440+ /// );
441+ /// ```
442+ pub fn or_insert_with < F : FnOnce ( ) -> V > ( self , default : F ) -> Result < & ' a mut V , V > {
443+ match self {
444+ Self :: Occupied ( entry) => Ok ( entry. into_mut ( ) ) ,
445+ Self :: Vacant ( entry) => entry. insert ( default ( ) ) ,
446+ }
447+ }
448+
449+ /// Ensures a value is in the entry by inserting, if empty, the result of
450+ /// the default function. This method allows for generating key-derived
451+ /// values for insertion by providing the default function a reference to
452+ /// the key that was moved during the `.entry(key)` method call.
453+ ///
454+ /// The reference to the moved key is provided so that cloning or copying
455+ /// the key is unnecessary, unlike with `.or_insert_with(|| ... )`.
456+ ///
457+ /// # Examples
458+ ///
459+ /// ```
460+ /// use heapless::FnvIndexMap;
461+ ///
462+ /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
463+ /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
464+ ///
465+ /// book_reviews
466+ /// .entry("Pride and Prejudice")
467+ /// .or_insert_with_key(|key| key.chars().count());
468+ ///
469+ /// assert_eq!(book_reviews["Pride and Prejudice"], 19);
470+ /// ```
471+ pub fn or_insert_with_key < F : FnOnce ( & K ) -> V > ( self , default : F ) -> Result < & ' a mut V , V > {
472+ match self {
473+ Self :: Occupied ( entry) => Ok ( entry. into_mut ( ) ) ,
474+ Self :: Vacant ( entry) => {
475+ let value = default ( entry. key ( ) ) ;
476+ entry. insert ( value)
477+ }
478+ }
479+ }
480+
481+ /// Returns a reference to this entry's key.
482+ ///
483+ /// # Examples
484+ ///
485+ /// ```
486+ /// use heapless::FnvIndexMap;
487+ ///
488+ /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
489+ /// let mut book_reviews = FnvIndexMap::<&str, &str, 16>::new();
490+ /// assert_eq!(
491+ /// book_reviews
492+ /// .entry("The Adventures of Sherlock Holmes")
493+ /// .key(),
494+ /// &"The Adventures of Sherlock Holmes"
495+ /// );
496+ /// ```
497+ pub fn key ( & self ) -> & K {
498+ match * self {
499+ Self :: Occupied ( ref entry) => entry. key ( ) ,
500+ Self :: Vacant ( ref entry) => entry. key ( ) ,
501+ }
502+ }
503+
504+ /// Provides in-place mutable access to an occupied entry before any
505+ /// potential inserts into the map.
506+ ///
507+ /// # Examples
508+ ///
509+ /// ```
510+ /// use heapless::FnvIndexMap;
511+ ///
512+ /// // A hash map with a capacity of 16 key-value pairs allocated on the stack
513+ /// let mut book_reviews = FnvIndexMap::<_, _, 16>::new();
514+ ///
515+ /// book_reviews
516+ /// .entry("Grimms' Fairy Tales")
517+ /// .and_modify(|e| *e = "Masterpiece.")
518+ /// .or_insert("Very enjoyable.");
519+ /// assert_eq!(book_reviews["Grimms' Fairy Tales"], "Very enjoyable.");
520+ /// ```
521+ pub fn and_modify < F > ( self , f : F ) -> Self
522+ where
523+ F : FnOnce ( & mut V ) ,
524+ {
525+ match self {
526+ Self :: Occupied ( mut entry) => {
527+ f ( entry. get_mut ( ) ) ;
528+ Self :: Occupied ( entry)
529+ }
530+ Self :: Vacant ( entry) => Self :: Vacant ( entry) ,
531+ }
532+ }
533+ }
534+
535+ impl < ' a , K , V , const N : usize > Entry < ' a , K , V , N >
536+ where
537+ K : Eq + Hash ,
538+ V : Default ,
539+ {
540+ /// Ensures a value is in the entry by inserting the default value if empty,
541+ /// and returns a mutable reference to the value in the entry.
542+ ///
543+ /// # Examples
544+ ///
545+ /// ```
546+ /// # fn main() {
547+ /// use heapless::FnvIndexMap;
548+ ///
549+ /// let mut book_reviews = FnvIndexMap::<&str, Option<&str>, 16>::new();
550+ ///
551+ /// book_reviews.entry("Pride and Prejudice").or_default();
552+ ///
553+ /// assert_eq!(book_reviews["Pride and Prejudice"], None);
554+ /// # }
555+ /// ```
556+ #[ inline]
557+ pub fn or_default ( self ) -> Result < & ' a mut V , V > {
558+ match self {
559+ Self :: Occupied ( entry) => Ok ( entry. into_mut ( ) ) ,
560+ Self :: Vacant ( entry) => entry. insert ( Default :: default ( ) ) ,
561+ }
562+ }
563+ }
564+
389565/// An occupied entry which can be manipulated
390566pub struct OccupiedEntry < ' a , K , V , const N : usize > {
391567 key : K ,
@@ -1316,6 +1492,85 @@ mod tests {
13161492 }
13171493 }
13181494
1495+ #[ test]
1496+ fn entry_or_insert ( ) {
1497+ let mut a: FnvIndexMap < _ , _ , 2 > = FnvIndexMap :: new ( ) ;
1498+ a. entry ( "k1" ) . or_insert ( "v1" ) . unwrap ( ) ;
1499+ assert_eq ! ( a[ "k1" ] , "v1" ) ;
1500+
1501+ a. entry ( "k2" ) . or_insert ( "v2" ) . unwrap ( ) ;
1502+ assert_eq ! ( a[ "k2" ] , "v2" ) ;
1503+
1504+ let result = a. entry ( "k3" ) . or_insert ( "v3" ) ;
1505+ assert_eq ! ( result, Err ( "v3" ) ) ;
1506+ }
1507+
1508+ #[ test]
1509+ fn entry_or_insert_with ( ) {
1510+ let mut a: FnvIndexMap < _ , _ , 2 > = FnvIndexMap :: new ( ) ;
1511+ a. entry ( "k1" ) . or_insert_with ( || "v1" ) . unwrap ( ) ;
1512+ assert_eq ! ( a[ "k1" ] , "v1" ) ;
1513+
1514+ a. entry ( "k2" ) . or_insert_with ( || "v2" ) . unwrap ( ) ;
1515+ assert_eq ! ( a[ "k2" ] , "v2" ) ;
1516+
1517+ let result = a. entry ( "k3" ) . or_insert_with ( || "v3" ) ;
1518+ assert_eq ! ( result, Err ( "v3" ) ) ;
1519+ }
1520+
1521+ #[ test]
1522+ fn entry_or_insert_with_key ( ) {
1523+ let mut a: FnvIndexMap < _ , _ , 2 > = FnvIndexMap :: new ( ) ;
1524+ a. entry ( "k1" )
1525+ . or_insert_with_key ( |key| key. chars ( ) . count ( ) )
1526+ . unwrap ( ) ;
1527+ assert_eq ! ( a[ "k1" ] , 2 ) ;
1528+
1529+ a. entry ( "k22" )
1530+ . or_insert_with_key ( |key| key. chars ( ) . count ( ) )
1531+ . unwrap ( ) ;
1532+ assert_eq ! ( a[ "k22" ] , 3 ) ;
1533+
1534+ let result = a. entry ( "k3" ) . or_insert_with_key ( |key| key. chars ( ) . count ( ) ) ;
1535+ assert_eq ! ( result, Err ( 2 ) ) ;
1536+ }
1537+
1538+ #[ test]
1539+ fn entry_key ( ) {
1540+ let mut a: FnvIndexMap < & str , & str , 2 > = FnvIndexMap :: new ( ) ;
1541+
1542+ assert_eq ! ( a. entry( "k1" ) . key( ) , & "k1" ) ;
1543+ }
1544+
1545+ #[ test]
1546+ fn entry_and_modify ( ) {
1547+ let mut a: FnvIndexMap < _ , _ , 2 > = FnvIndexMap :: new ( ) ;
1548+ a. insert ( "k1" , "v1" ) . unwrap ( ) ;
1549+ a. entry ( "k1" ) . and_modify ( |e| * e = "modified v1" ) ;
1550+
1551+ assert_eq ! ( a[ "k1" ] , "modified v1" ) ;
1552+
1553+ a. entry ( "k2" )
1554+ . and_modify ( |e| * e = "v2" )
1555+ . or_insert ( "default v2" )
1556+ . unwrap ( ) ;
1557+
1558+ assert_eq ! ( a[ "k2" ] , "default v2" ) ;
1559+ }
1560+
1561+ #[ test]
1562+ fn entry_or_default ( ) {
1563+ let mut a: FnvIndexMap < & str , Option < u32 > , 2 > = FnvIndexMap :: new ( ) ;
1564+ a. entry ( "k1" ) . or_default ( ) . unwrap ( ) ;
1565+
1566+ assert_eq ! ( a[ "k1" ] , None ) ;
1567+
1568+ let mut b: FnvIndexMap < & str , u8 , 2 > = FnvIndexMap :: new ( ) ;
1569+ b. entry ( "k2" ) . or_default ( ) . unwrap ( ) ;
1570+
1571+ assert_eq ! ( b[ "k2" ] , 0 ) ;
1572+ }
1573+
13191574 #[ test]
13201575 fn into_iter ( ) {
13211576 let mut src: FnvIndexMap < _ , _ , 4 > = FnvIndexMap :: new ( ) ;
0 commit comments