use super::get::{Get, GetMut};
use super::hlist::Cons;
use super::path::Here;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Context<L>(pub L);
impl<L> AsRef<L> for Context<L> {
#[inline]
fn as_ref(&self) -> &L {
&self.0
}
}
impl<L> AsMut<L> for Context<L> {
#[inline]
fn as_mut(&mut self) -> &mut L {
&mut self.0
}
}
impl<L> Context<L> {
#[inline]
pub const fn new(list: L) -> Self {
Self(list)
}
#[inline]
pub fn into_inner(self) -> L {
self.0
}
#[inline]
pub fn get<K>(&self) -> &<L as Get<K, Here>>::Target
where
L: Get<K, Here>,
{
Get::<K, Here>::get(&self.0)
}
#[inline]
pub fn get_path<K, P>(&self) -> &<L as Get<K, P>>::Target
where
L: Get<K, P>,
{
Get::<K, P>::get(&self.0)
}
#[inline]
pub fn get_mut<K>(&mut self) -> &mut <L as GetMut<K, Here>>::Target
where
L: GetMut<K, Here>,
{
GetMut::<K, Here>::get_mut(&mut self.0)
}
#[inline]
pub fn get_mut_path<K, P>(&mut self) -> &mut <L as GetMut<K, P>>::Target
where
L: GetMut<K, P>,
{
GetMut::<K, P>::get_mut(&mut self.0)
}
#[inline]
pub fn prepend<H>(self, head: H) -> Context<Cons<H, L>> {
prepend_cell(head, self)
}
}
impl<H, T> Context<Cons<H, T>> {
#[inline]
pub fn head(&self) -> &H {
&self.0.0
}
#[inline]
pub fn tail_list(&self) -> &T {
&self.0.1
}
#[inline]
pub fn into_tail(self) -> Context<T> {
Context::new(self.0.1)
}
}
#[inline]
pub fn prepend_cell<H, L>(head: H, ctx: Context<L>) -> Context<Cons<H, L>> {
Context::new(Cons(head, ctx.into_inner()))
}
impl<K: ?Sized, P, L> Get<K, P> for Context<L>
where
L: Get<K, P>,
{
type Target = <L as Get<K, P>>::Target;
#[inline]
fn get(&self) -> &Self::Target {
self.0.get()
}
}
impl<K: ?Sized, P, L> GetMut<K, P> for Context<L>
where
L: GetMut<K, P>,
{
type Target = <L as GetMut<K, P>>::Target;
#[inline]
fn get_mut(&mut self) -> &mut Self::Target {
self.0.get_mut()
}
}