#![no_std]
use core::any::TypeId;
pub trait KeyPathValueTarget {
type Target: Sized;
}
impl<T: Sized> KeyPathValueTarget for &T {
type Target = T;
}
impl<T: Sized> KeyPathValueTarget for &mut T {
type Target = T;
}
pub trait Readable<Root, Value> {
fn get(&self, root: Root) -> Option<Value>;
}
pub trait Writable<MutRoot, MutValue> {
fn set(&self, root: MutRoot) -> Option<MutValue>;
}
pub trait KeyPath<Root, Value, MutRoot, MutValue>:
Readable<Root, Value> + Writable<MutRoot, MutValue>
{
}
impl<T, Root, Value, MutRoot, MutValue> KeyPath<Root, Value, MutRoot, MutValue> for T where
T: Readable<Root, Value> + Writable<MutRoot, MutValue>
{
}
pub trait KpTrait<R, V, Root, Value, MutRoot, MutValue>:
Readable<Root, Value> + Writable<MutRoot, MutValue>
{
fn type_id_of_root() -> TypeId
where
R: 'static,
{
TypeId::of::<R>()
}
fn type_id_of_value() -> TypeId
where
V: 'static,
{
TypeId::of::<V>()
}
fn then<SV, SubValue, MutSubValue, Next>(
self,
next: Next,
) -> impl KeyPath<Root, SubValue, MutRoot, MutSubValue>
where
Self: Sized,
SubValue: core::borrow::Borrow<SV>,
MutSubValue: core::borrow::BorrowMut<SV>,
Next: Readable<Value, SubValue> + Writable<MutValue, MutSubValue> + Clone;
}
pub trait AccessorTrait<Root, Value, MutRoot, MutValue>:
Readable<Root, Value> + Writable<MutRoot, MutValue>
{
fn get_optional(&self, root: Option<Root>) -> Option<Value> {
root.and_then(|r| Readable::get(self, r))
}
fn get_mut_optional(&self, root: Option<MutRoot>) -> Option<MutValue> {
root.and_then(|r| Writable::set(self, r))
}
fn get_or_else<F>(&self, root: Root, f: F) -> Value
where
F: FnOnce() -> Value,
{
Readable::get(self, root).unwrap_or_else(f)
}
fn get_mut_or_else<F>(&self, root: MutRoot, f: F) -> MutValue
where
F: FnOnce() -> MutValue,
{
Writable::set(self, root).unwrap_or_else(f)
}
}