@@ -386,6 +386,182 @@ pub enum Entry<'a, K, V, const N: usize> {
386
386
Vacant ( VacantEntry < ' a , K , V , N > ) ,
387
387
}
388
388
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
+
389
565
/// An occupied entry which can be manipulated
390
566
pub struct OccupiedEntry < ' a , K , V , const N : usize > {
391
567
key : K ,
@@ -1316,6 +1492,85 @@ mod tests {
1316
1492
}
1317
1493
}
1318
1494
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
+
1319
1574
#[ test]
1320
1575
fn into_iter ( ) {
1321
1576
let mut src: FnvIndexMap < _ , _ , 4 > = FnvIndexMap :: new ( ) ;
0 commit comments