Skip to main content

Entry

Enum Entry 

Source
pub enum Entry<'a, T: BiHashItem, S = DefaultHashBuilder, A: Allocator = Global> {
    Vacant(VacantEntry<'a, T, S, A>),
    Occupied(OccupiedEntry<'a, T, S, A>),
}
Expand description

An implementation of the Entry API for BiHashMap.

§Differences from single-key entries

The shape of this type differs from those provided for the other map types, because it is possible for one of the two keys provided to correspond to an existing entry, while the other does not.

VacantEntry corresponds to situations where neither key is present. To insert an entry corresponding to the two keys, use VacantEntry::insert.

OccupiedEntry represents situations where either the keys correspond to different entries, or where only one of the keys is present. It provides the following methods:

§Examples

use iddqd::{BiHashItem, BiHashMap, bi_hash_map, bi_upcast};

#[derive(Debug, PartialEq, Eq)]
struct Item {
    id: u32,
    name: String,
    value: i32,
}

impl BiHashItem for Item {
    type K1<'a> = u32;
    type K2<'a> = &'a str;

    fn key1(&self) -> Self::K1<'_> {
        self.id
    }
    fn key2(&self) -> Self::K2<'_> {
        &self.name
    }
    bi_upcast!();
}

let mut map = BiHashMap::new();
map.insert_unique(Item { id: 1, name: "foo".to_string(), value: 42 })
    .unwrap();

// Get an existing entry. Both keys point to the same item, so the
// entry is unique.
match map.entry(1, "foo") {
    bi_hash_map::Entry::Occupied(entry) => {
        assert!(entry.is_unique());
        assert_eq!(entry.get().as_unique().unwrap().value, 42);
    }
    bi_hash_map::Entry::Vacant(_) => panic!("Should be occupied"),
}

// Try to get a non-existing entry.
match map.entry(2, "bar") {
    bi_hash_map::Entry::Occupied(_) => panic!("Should be vacant"),
    bi_hash_map::Entry::Vacant(entry) => {
        entry.insert(Item { id: 2, name: "bar".to_string(), value: 99 });
    }
}

assert_eq!(map.len(), 2);

// An entry is non-unique when its two keys point to different items.
// Here, id 1 belongs to "foo" but name "bar" belongs to id 2.
match map.entry(1, "bar") {
    bi_hash_map::Entry::Occupied(entry) => {
        assert!(entry.is_non_unique());
        let entry_ref = entry.get();
        assert_eq!(entry_ref.by_key1().unwrap().name, "foo");
        assert_eq!(entry_ref.by_key2().unwrap().id, 2);
        assert_eq!(entry_ref.as_unique(), None);
    }
    bi_hash_map::Entry::Vacant(_) => panic!("Should be occupied"),
}

// An entry is also non-unique when only one of its keys is present.
match map.entry(1, "nonexistent") {
    bi_hash_map::Entry::Occupied(mut entry) => {
        assert!(entry.is_non_unique());
        let entry_ref = entry.get();
        assert_eq!(entry_ref.by_key1().unwrap().id, 1);
        assert_eq!(entry_ref.by_key2(), None);

        // Inserting overwrites whichever items the keys matched,
        // returning them. Only id 1 ("foo") was present, so it alone
        // is returned.
        let replaced = entry.insert(Item {
            id: 1,
            name: "nonexistent".to_string(),
            value: 7,
        });
        assert_eq!(replaced.len(), 1);
        assert_eq!(replaced[0].name, "foo");

        // The entry is now unique: both keys point to the new item.
        assert!(entry.is_unique());
        assert_eq!(entry.get().as_unique().unwrap().value, 7);
    }
    bi_hash_map::Entry::Vacant(_) => panic!("Should be occupied"),
}

// "foo" was overwritten in place, so the map still holds two items.
assert_eq!(map.get1(&1).unwrap().name, "nonexistent");
assert_eq!(map.get2(&"foo"), None);
assert_eq!(map.len(), 2);

Variants§

§

Vacant(VacantEntry<'a, T, S, A>)

A vacant entry: none of the provided keys are present.

§

Occupied(OccupiedEntry<'a, T, S, A>)

An occupied entry where at least one of the keys is present in the map.

Implementations§

Source§

impl<'a, T: BiHashItem, S: Clone + BuildHasher, A: Allocator> Entry<'a, T, S, A>

Source

pub fn or_insert(self, default: T) -> OccupiedEntryMut<'a, T, S>

Ensures a value is in the entry by inserting the default if empty, and returns a mutable reference to the value in the entry.

§Panics

Panics if the key hashes to a different value than the one passed into BiHashMap::entry.

Source

pub fn or_insert_with<F: FnOnce() -> T>( self, default: F, ) -> OccupiedEntryMut<'a, T, S>

Ensures a value is in the entry by inserting the result of the default function if empty, and returns a mutable reference to the value in the entry.

§Panics

Panics if the key hashes to a different value than the one passed into BiHashMap::entry.

Source

pub fn and_modify<F>(self, f: F) -> Self
where F: FnMut(RefMut<'_, T, S>),

Provides in-place mutable access to occupied entries before any potential inserts into the map.

F is called for each entry that matches the provided keys.

Trait Implementations§

Source§

impl<'a, T: BiHashItem, S, A: Allocator> Debug for Entry<'a, T, S, A>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, T, S, A> Freeze for Entry<'a, T, S, A>

§

impl<'a, T, S, A> RefUnwindSafe for Entry<'a, T, S, A>

§

impl<'a, T, S, A> Send for Entry<'a, T, S, A>
where S: Send, T: Send, A: Send,

§

impl<'a, T, S, A> Sync for Entry<'a, T, S, A>
where S: Sync, T: Sync, A: Sync,

§

impl<'a, T, S, A> Unpin for Entry<'a, T, S, A>

§

impl<'a, T, S, A> UnsafeUnpin for Entry<'a, T, S, A>

§

impl<'a, T, S = RandomState, A = Global> !UnwindSafe for Entry<'a, T, S, A>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.