Skip to content

Commit

Permalink
Merge pull request #84 from EriKWDev/ErikWDev/entry-or-inster-api
Browse files Browse the repository at this point in the history
more functions to match standard entry api
  • Loading branch information
JesperAxelsson authored Jan 29, 2025
2 parents 4b38a13 + 0143069 commit bdbe95a
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,55 @@ impl<'a, K: IntKey, V> Entry<'a, K, V> {

(cache_ix, vals_ix)
}

/// Ensures a value is in the entry by inserting the provided value if empty, and returns
/// a mutable reference to the value in the entry.
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default),
}
}

/// Ensures a value is in the entry by inserting the result of the provided function if empty,
/// and returns a mutable reference to the value in the entry.
pub fn or_insert_with<F>(self, default: F) -> &'a mut V
where
F: FnOnce() -> V,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default()),
}
}

/// Ensures a value is in the entry by inserting, if empty, the result of the provided function.
pub fn or_insert_with_key<F>(self, default: F) -> &'a mut V
where
F: FnOnce(K) -> V,
{
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let d = default(entry.key);
entry.insert(d)
}
}
}
}

impl<'a, K: IntKey, V> Entry<'a, K, V>
where
V: Default,
{
/// Ensures a value is in the entry by inserting the default value if empty,
/// and returns a mutable reference to the value in the entry.
pub fn or_default(self) -> &'a mut V {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(Default::default()),
}
}
}

/// A view into an occupied entry in a [`IntMap`]. It is part of the [`Entry`] enum.
Expand Down
88 changes: 88 additions & 0 deletions tests/basic_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,94 @@ mod tests {
assert_eq!(map.len(), 0);
}

#[test]
fn entry_or_insert_with() {
let mut map: IntMap<u64, u64> = IntMap::new();

map.insert(10, 100);

let mut triggered = false;
let v = map.entry(10).or_insert_with(|| {
triggered = true;
1337
});

assert!(!triggered);
assert_ne!(*v, 1337);

let mut triggered = false;
let v = map.entry(239048).or_insert_with(|| {
triggered = true;
42
});

assert!(triggered);
assert_eq!(*v, 42);
}

#[test]
fn entry_or_default() {
let mut map: IntMap<u64, u64> = IntMap::new();

let cases = [
(10, 1337),
(1028390123, 1337),
(12098312, 08082934),
(123981, 1337),
(23498902348, 1337),
(2198312093, 12983),
];

let def: u64 = Default::default();

for (key, value) in cases {
assert!(!map.contains_key(key));
let it = map.entry(key).or_default();

assert_eq!(*it, def);
assert_eq!(*map.get(key).unwrap(), def);

let it = map.entry(key).or_insert(value);
assert_ne!(*it, value);
assert_eq!(*it, def);

*it = value;
let it = map.entry(key).or_default();
assert_ne!(*it, def);
assert_eq!(*it, value);
}
}

#[test]
fn entry_or_insert() {
let mut map: IntMap<u64, u64> = IntMap::new();

let cases = [
(10, 1337, 424242, 69),
(10280123, 1337, 424242, 19283),
(12091292, 08082934, 424242, 1029381092),
(12390331, 1337, 429138, 19283),
(23492348, 3912, 93925, 12309182),
(21982093, 12983, 491832, 120398213),
];

for (key, value_1, value_2, value_3) in cases {
assert!(!map.contains_key(key));
let it = map.entry(key).or_insert(value_1);

assert_eq!(*it, value_1);
assert_eq!(*map.get(key).unwrap(), value_1);

let it = map.entry(key).or_insert(value_2);
assert_ne!(*it, value_2);
assert_eq!(*it, value_1);

*it = value_3;
let it = map.entry(key).or_insert(value_2);
assert_eq!(*it, value_3);
}
}

#[test]
fn test_debug_features() {
let count = 20_000;
Expand Down

0 comments on commit bdbe95a

Please sign in to comment.