use super::hlist::*;
use super::labelled::*;
use core::marker::PhantomData;
use core::ops::Add;
#[derive(Clone, Copy, Debug)]
pub struct Path<T>(PhantomData<T>);
impl<T> Path<T> {
pub fn new() -> Path<T> {
Path(PhantomData)
}
pub fn get<V, I, O>(&self, o: O) -> V
where
O: PathTraverser<Self, I, TargetValue = V>,
{
o.get()
}
}
impl<T> Default for Path<T> {
fn default() -> Self {
Self::new()
}
}
pub trait PathTraverser<Path, Indices> {
type TargetValue;
fn get(self) -> Self::TargetValue;
}
impl<Name, PluckIndex, Traversable> PathTraverser<Path<HCons<Name, HNil>>, PluckIndex>
for Traversable
where
Traversable: IntoLabelledGeneric,
<Traversable as IntoLabelledGeneric>::Repr: ByNameFieldPlucker<Name, PluckIndex>,
{
type TargetValue = <<Traversable as IntoLabelledGeneric>::Repr as ByNameFieldPlucker<
Name,
PluckIndex,
>>::TargetValue;
#[inline(always)]
fn get(self) -> Self::TargetValue {
self.into().pluck_by_name().0.value
}
}
impl<HeadName, TailNames, HeadPluckIndex, TailPluckIndices, Traversable>
PathTraverser<Path<HCons<HeadName, Path<TailNames>>>, HCons<HeadPluckIndex, TailPluckIndices>>
for Traversable
where
Traversable: IntoLabelledGeneric,
<Traversable as IntoLabelledGeneric>::Repr: ByNameFieldPlucker<HeadName, HeadPluckIndex>,
<<Traversable as IntoLabelledGeneric>::Repr as ByNameFieldPlucker<HeadName, HeadPluckIndex>>::TargetValue:
PathTraverser<Path<TailNames>, TailPluckIndices>,
{
type TargetValue = <<<Traversable as IntoLabelledGeneric>::Repr as ByNameFieldPlucker<HeadName, HeadPluckIndex>>::TargetValue as
PathTraverser<Path<TailNames>, TailPluckIndices>>::TargetValue ;
#[inline(always)]
fn get(self) -> Self::TargetValue {
self.into().pluck_by_name().0.value.get()
}
}
impl<Name, RHSParam> Add<Path<RHSParam>> for Path<HCons<Name, HNil>> {
type Output = Path<HCons<Name, Path<RHSParam>>>;
#[inline(always)]
fn add(self, _: Path<RHSParam>) -> Self::Output {
Path::new()
}
}
impl<Name, Tail, RHSParam> Add<Path<RHSParam>> for Path<HCons<Name, Path<Tail>>>
where
Path<Tail>: Add<Path<RHSParam>>,
{
#[allow(clippy::type_complexity)]
type Output = Path<HCons<Name, <Path<Tail> as Add<Path<RHSParam>>>::Output>>;
#[inline(always)]
fn add(self, _: Path<RHSParam>) -> <Self as Add<Path<RHSParam>>>::Output {
Path::new()
}
}