#![no_std]
#![allow(nonstandard_style)]
pub trait Append<A>: Join<(A,)> {
fn push(self, other: A) -> Self::Out where Self: Sized, A: Sized;
fn pop(tuple: Self::Out) -> (Self, A) where Self: Sized, A: Sized;
}
impl<A, T> Append<A> for T where T: Join<(A,)>{
fn push(self, other: A) -> Self::Out where Self: Sized, A: Sized {
self.join((other,))
}
fn pop(tuple: Self::Out) -> (Self, A) where Self: Sized, A: Sized {
let (a, (b, )) = Self::split(tuple);
return (a, b);
}
}
pub trait Join<A> {
type Out;
fn join(self, other: A) -> Self::Out where Self: Sized, A: Sized;
fn split(tuple: Self::Out) -> (Self, A) where Self: Sized, A: Sized;
}
pub trait Appended<A, B> {
fn pop(self) -> (A, B);
}
pub trait Joined<A, B> {
fn split(self) -> (A, B);
}
impl<A, B, T> Appended<A, B> for T where A: Append<B, Out = T>{
fn pop(self) -> (A, B) {
A::pop(self)
}
}
impl<A, B, T> Joined<A, B> for T where A: Join<B, Out = T>{
fn split(self) -> (A, B) {
A::split(self)
}
}
macro_rules! tuple_join_y {
($($x: ident)* ,) => {
impl<$($x,)*> Join<()> for ($($x,)*) {
type Out = ($($x,)*);
fn join(self, _: ()) -> Self::Out {
self
}
fn split(out: Self::Out) -> (Self, ()) {
(out, ())
}
}
};
($($x: ident)*, $y0:ident $($y: ident)*) => {
impl<$($x,)* $y0,$($y,)*> Join<($y0,$($y,)*)> for ($($x,)*) {
type Out = ($($x,)* $y0,$($y,)*);
fn join(self, ($y0,$($y,)*): ($y0,$($y,)*)) -> Self::Out {
let ($($x,)*) = self;
($($x,)* $y0,$($y,)*)
}
fn split(($($x,)* $y0,$($y,)*): Self::Out) -> (Self, ($y0,$($y,)*)) {
(($($x,)*), ($y0,$($y,)*))
}
}
tuple_join_y!($($x)*, $($y)*);
};
}
macro_rules! tuple_join {
(, $y0:ident $($y: ident)*) => {
impl<$y0,$($y,)*> Join<($y0,$($y),*)> for () {
type Out = ($y0,$($y,)*);
fn join(self, other: ($y0,$($y,)*)) -> Self::Out {
other
}
fn split(out: Self::Out) -> (Self, ($y0,$($y,)*)) {
((), out)
}
}
tuple_join_y!(, $($y)*);
};
($x0: ident $($x: ident)*, $y0:ident $($y: ident)*) => {
impl<$x0,$($x,)* $y0,$($y,)*> Join<($y0,$($y,)*)> for ($x0,$($x,)*) {
type Out = ($x0,$($x,)* $y0,$($y,)*);
fn join(self, ($y0,$($y,)*): ($y0,$($y,)*)) -> Self::Out {
let ($x0,$($x,)*) = self;
($x0,$($x,)* $y0,$($y,)*)
}
fn split(($x0,$($x,)* $y0,$($y,)*): Self::Out) -> (Self, ($y0,$($y,)*)) {
(($x0,$($x,)*), ($y0,$($y,)*))
}
}
tuple_join!($($x)*, $y0 $($y)*);
tuple_join_y!($x0 $($x)*, $($y)*);
};
}
tuple_join!(
A B C D E F G H I J K L M,
N O P Q R S T U V W X Y Z
);