mapgraph 0.12.0

A directed graph that can also be used as an arbitrary map.
Documentation
//! Provides implementations of the map traits for [`SlotMap`], [`HopSlotMap`], [`DenseSlotMap`] and
//! [`SecondaryMap`].

use crate::map::{ExtKeyMap, IntKeyMap, Map, MapWithCapacity, OccupiedError};
use slotmap::{new_key_type, secondary, DenseSlotMap, HopSlotMap, SecondaryMap, SlotMap};
#[cfg(feature = "std")]
use slotmap::{sparse_secondary, SparseSecondaryMap};
pub use slotmap::{Key, KeyData};

new_key_type! {
    /// An index that is expected to be used for [`Graph`] nodes in graphs that store nodes in
    /// [`SlotMap`]s.
    pub struct NodeIndex;

    /// An index that is expected to be used for [`Graph`] edges in graphs that store edges in
    /// [`SlotMap`]s.
    pub struct EdgeIndex;
}

macro_rules! impl_primary_map {
    ($name:ident, $sub_mod:ident) => {
        impl<K: Key + 'static, T> Map<T> for $name<K, T> {
            type Key = K;
            type Iter<'a> = slotmap::$sub_mod::Iter<'a, K, T> where Self: 'a, T: 'a;
            type IterMut<'a> = slotmap::$sub_mod::IterMut<'a, K, T> where Self: 'a, T: 'a;

            fn len(&self) -> usize {
                $name::len(self)
            }

            fn is_empty(&self) -> bool {
                $name::is_empty(self)
            }

            fn contains_key(&self, key: Self::Key) -> bool {
                $name::contains_key(self, key)
            }

            fn get(&self, index: Self::Key) -> Option<&T> {
                $name::get(self, index)
            }

            fn get_mut(&mut self, index: Self::Key) -> Option<&mut T> {
                $name::get_mut(self, index)
            }

            fn remove(&mut self, index: Self::Key) -> Option<T> {
                $name::remove(self, index)
            }

            fn clear(&mut self) {
                $name::clear(self)
            }

            fn iter(&self) -> Self::Iter<'_> {
                $name::iter(self)
            }

            fn iter_mut(&mut self) -> Self::IterMut<'_> {
                $name::iter_mut(self)
            }
        }

        impl<K: Key + 'static, T> MapWithCapacity<T> for $name<K, T> {
            fn with_capacity(capacity: usize) -> Self {
                $name::with_capacity_and_key(capacity)
            }

            fn capacity(&self) -> usize {
                $name::capacity(self)
            }

            fn reserve(&mut self, additional: usize) {
                $name::reserve(self, additional)
            }
        }

        impl<K: Key + 'static, T> IntKeyMap<T> for $name<K, T> {
            fn insert(&mut self, value: T) -> Self::Key {
                $name::insert(self, value)
            }

            fn insert_with_key<F: FnOnce(Self::Key) -> T>(&mut self, f: F) -> Self::Key {
                $name::insert_with_key(self, f)
            }
        }
    };
}

impl_primary_map!(SlotMap, basic);
impl_primary_map!(HopSlotMap, hop);
impl_primary_map!(DenseSlotMap, dense);

macro_rules! impl_secondary_map {
    ($name:ident, $sub_mod:ident) => {
        impl<K: Key + 'static, T> Map<T> for $name<K, T> {
            type Key = K;
            type Iter<'a> = $sub_mod::Iter<'a, K, T> where Self: 'a, T: 'a;
            type IterMut<'a> = $sub_mod::IterMut<'a, K, T> where Self: 'a, T: 'a;

            fn len(&self) -> usize {
                $name::len(self)
            }

            fn is_empty(&self) -> bool {
                $name::is_empty(self)
            }

            fn contains_key(&self, index: Self::Key) -> bool {
                $name::contains_key(self, index)
            }

            fn get(&self, index: Self::Key) -> Option<&T> {
                $name::get(self, index)
            }

            fn get_mut(&mut self, index: Self::Key) -> Option<&mut T> {
                $name::get_mut(self, index)
            }

            fn remove(&mut self, index: Self::Key) -> Option<T> {
                $name::remove(self, index)
            }

            fn clear(&mut self) {
                $name::clear(self)
            }

            fn iter(&self) -> Self::Iter<'_> {
                $name::iter(self)
            }

            fn iter_mut(&mut self) -> Self::IterMut<'_> {
                $name::iter_mut(self)
            }
        }

        impl<K: Key + 'static, T> ExtKeyMap<T> for $name<K, T> {
            fn try_insert(&mut self, key: Self::Key, value: T) -> Result<(), OccupiedError> {
                match $name::entry(self, key) {
                    Some($sub_mod::Entry::Vacant(entry)) => {
                        entry.insert(value);
                        Ok(())
                    }
                    // None is returned for slots which are occupied with newer key versions and for
                    // null keys. Both are OK since it's impossible to insert values for these
                    // keys anyway.
                    Some($sub_mod::Entry::Occupied(_)) | None => Err(OccupiedError),
                }
            }

            fn replace(&mut self, key: Self::Key, value: T) -> Option<T> {
                $name::insert(self, key, value)
            }
        }

        impl<K: Key + 'static, T> MapWithCapacity<T> for $name<K, T> {
            fn with_capacity(capacity: usize) -> Self {
                $name::with_capacity(capacity)
            }

            fn capacity(&self) -> usize {
                $name::capacity(self)
            }

            fn reserve(&mut self, _additional: usize) {}
        }
    };
}

impl_secondary_map!(SecondaryMap, secondary);
#[cfg(feature = "std")]
impl_secondary_map!(SparseSecondaryMap, sparse_secondary);