use std::{borrow::Borrow, cmp::Eq, fmt::Debug, hash::Hash};
pub trait Key: Hash + Eq + Send + Sync + Debug + 'static {}
impl<T: Hash + Eq + Send + Sync + Debug + 'static> Key for T {}
pub trait Keyed {
type Key: Key;
}
impl<T: Key + Clone> Keyed for T {
type Key = T;
}
pub trait PartialKeyed {
type PartialKey: Key;
}
pub trait Keyring<State>: Keyed {
type KeyRef<'a>: Borrow<Self::Key> + 'a
where
Self: 'a,
State: 'a;
fn key_for<'a>(&'a self, state: &'a State) -> Self::KeyRef<'a>
where
Self: 'a,
State: 'a;
}
pub trait SelfKey: Keyed {
type KeyRef<'a>: Borrow<Self::Key> + 'a
where
Self: 'a;
fn key<'a>(&'a self) -> Self::KeyRef<'a>
where
Self: 'a;
}
impl<T: Key + Clone> SelfKey for T {
type KeyRef<'a>
= &'a Self::Key
where
Self: 'a;
fn key<'a>(&'a self) -> &'a Self::Key
where
Self: 'a,
{
self
}
}
pub struct SelfKeyring<K>(std::marker::PhantomData<K>);
impl<K> SelfKeyring<K> {
pub fn new() -> Self {
Self(Default::default())
}
}
impl<K> Default for SelfKeyring<K> {
fn default() -> Self {
Self::new()
}
}
impl<K: Key> Keyed for SelfKeyring<K> {
type Key = K;
}
impl<State: SelfKey> Keyring<State> for SelfKeyring<State::Key> {
type KeyRef<'a>
= State::KeyRef<'a>
where
State: 'a;
fn key_for<'a>(&'a self, state: &'a State) -> State::KeyRef<'a>
where
State: 'a,
{
state.key()
}
}
pub struct SelfPartialKeyring<K>(std::marker::PhantomData<K>);
impl<K> SelfPartialKeyring<K> {
pub fn new() -> Self {
Self(Default::default())
}
}
impl<K> Default for SelfPartialKeyring<K> {
fn default() -> Self {
Self::new()
}
}
impl<K: Key> PartialKeyed for SelfPartialKeyring<K> {
type PartialKey = K;
}
impl<K: Key> Keyed for SelfPartialKeyring<K> {
type Key = Option<K>;
}
impl<K: Key, State: SelfKey<Key = Option<K>>> Keyring<State> for SelfPartialKeyring<K> {
type KeyRef<'a>
= State::KeyRef<'a>
where
Self: 'a,
State: 'a,
K: 'a;
fn key_for<'a>(&'a self, state: &'a State) -> State::KeyRef<'a>
where
Self: 'a,
State: 'a,
K: 'a,
{
state.key()
}
}