use handle::{new_handle, Handle, Skip, Take};
use lookup::Lookup;
pub trait Append<T> {
type Output: PrefixedWith<Self> + Lookup<T, Self::Navigator>;
type Navigator;
fn append(self, t: T) -> (Self::Output, Handle<T, Self::Navigator>);
}
impl<T, U, V> Append<T> for (U, V)
where
V: Append<T>,
{
type Output = (U, <V as Append<T>>::Output);
type Navigator = (Skip, <V as Append<T>>::Navigator);
fn append(self, t: T) -> (Self::Output, Handle<T, Self::Navigator>) {
let (u, v) = self;
((u, v.append(t).0), new_handle())
}
}
impl<T> Append<T> for () {
type Output = (T, ());
type Navigator = Take;
fn append(self, t: T) -> (Self::Output, Handle<T, Self::Navigator>) {
((t, ()), new_handle())
}
}
pub trait PrefixedWith<T>
where
T: ?Sized,
{
}
impl<U, V0, V1> PrefixedWith<(U, V0)> for (U, V1) where V1: PrefixedWith<V0> {}
impl<U> PrefixedWith<()> for (U, ()) {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn append_test() {
let (list, _): ((u8, ()), Handle<u8, Take>) = ().append(1u8);
let (list, _) = list.append(2u8);
let (list, _) = list.append(3u8);
assert_eq!(list.0, 1);
assert_eq!((list.1).0, 2);
assert_eq!(((list.1).1).0, 3);
}
}