ty_map_gen 0.1.6

A type projecting map generator.
Documentation
use std::any::TypeId;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::hash::Hash;

pub trait DualKeyIndex<T: ?Sized> {
    fn ty(&self) -> TypeId;
    fn name(&self) -> &T;
}

impl<T: ?Sized> PartialEq for dyn DualKeyIndex<T> + '_
where
    T: PartialEq,
{
    fn eq(&self, other: &Self) -> bool {
        self.ty() == other.ty() && self.name() == other.name()
    }
}

impl<T: ?Sized> Eq for dyn DualKeyIndex<T> + '_ where T: Eq {}

impl<T: ?Sized> PartialOrd for dyn DualKeyIndex<T> + '_
where
    T: PartialOrd,
{
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
        match self.ty().cmp(&other.ty()) {
            Ordering::Equal => self.name().partial_cmp(other.name()),
            order => Some(order),
        }
    }
}

impl<T: ?Sized> Ord for dyn DualKeyIndex<T> + '_
where
    T: Ord,
{
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.ty()
            .cmp(&other.ty())
            .then(self.name().cmp(other.name()))
    }
}

impl<T: ?Sized> Hash for dyn DualKeyIndex<T> + '_
where
    T: Hash,
{
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.ty().hash(state);
        self.name().hash(state);
    }
}

impl<A, T: ?Sized> DualKeyIndex<T> for (TypeId, A)
where
    A: Borrow<T>,
{
    fn ty(&self) -> TypeId {
        self.0
    }

    fn name(&self) -> &T {
        self.1.borrow()
    }
}
impl<'a, A, T: ?Sized> Borrow<dyn DualKeyIndex<T> + 'a> for (TypeId, A)
where
    A: Borrow<T> + 'a,
{
    fn borrow(&self) -> &(dyn DualKeyIndex<T> + 'a) {
        self
    }
}