romap 0.4.0

A trait for read-only-maps
Documentation
use crate::RoMap;
use std::borrow::Borrow;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::hash::{BuildHasher, Hash};

macro_rules! impl_map {
    ($Container:ty) => {
        fn contains_key(self, k: &KO) -> bool {
            <$Container>::contains_key(self, k)
        }

        fn get(self, k: &KO) -> Option<&'a V> {
            <$Container>::get(self, k)
        }

        fn get_key_value(self, k: &KO) -> Option<(&'a KO, &'a V)> {
            let (k, v) = <$Container>::get_key_value(self, k)?;
            Some((k.borrow(), v))
        }

        fn is_empty(self) -> bool {
            <$Container>::is_empty(self)
        }

        fn len(self) -> usize {
            <$Container>::len(self)
        }

        fn keys(self) -> impl Iterator<Item = &'a KO> {
            <$Container>::keys(self).map(Borrow::borrow)
        }

        fn values(self) -> impl Iterator<Item = &'a V> {
            <$Container>::values(self)
        }

        fn iter(self) -> impl Iterator<Item = (&'a KO, &'a V)> {
            <$Container>::iter(self).map(|(k, v)| (k.borrow(), v))
        }
    };
}

impl<'a, KI: Hash + Eq + Borrow<KO>, V: 'a, KO: Hash + Eq + ?Sized + 'a, S: BuildHasher>
    RoMap<'a, KO, V> for &'a HashMap<KI, V, S>
{
    impl_map!(HashMap::<KI, V, S>);
}

impl<'a, KI: Ord + Borrow<KO>, V: 'a, KO: Ord + ?Sized + 'a> RoMap<'a, KO, V>
    for &'a BTreeMap<KI, V>
{
    const ITER_ORDER_SORTED: bool = true;

    impl_map!(BTreeMap::<KI, V>);
}

macro_rules! impl_set {
    ($Container:ty) => {
        fn contains_key(self, k: &KO) -> bool {
            <$Container>::contains(self, k)
        }

        fn get_key_value(self, k: &KO) -> Option<(&'a KO, &'a ())> {
            Some((<$Container>::get(self, k)?.borrow(), &()))
        }

        fn is_empty(self) -> bool {
            <$Container>::is_empty(self)
        }

        fn len(self) -> usize {
            <$Container>::len(self)
        }

        fn iter(self) -> impl Iterator<Item = (&'a KO, &'a ())> {
            <$Container>::iter(self).map(|k| (k.borrow(), &()))
        }
    };
}

impl<'a, KI: Hash + Eq + Borrow<KO>, KO: Hash + Eq + ?Sized + 'a, S: BuildHasher> RoMap<'a, KO, ()>
    for &'a HashSet<KI, S>
{
    impl_set!(HashSet<KI,S>);
}

impl<'a, KI: Ord + Borrow<KO>, KO: Ord + ?Sized + 'a> RoMap<'a, KO, ()> for &'a BTreeSet<KI> {
    const ITER_ORDER_SORTED: bool = true;
    impl_set!(BTreeSet<KI>);
}