use crate::Binding;
pub trait Project: Sized {
type Projected;
fn project(source: &Binding<Self>) -> Self::Projected;
}
macro_rules! tuples {
($macro:ident) => {
$macro!((T0, 0), (T1, 1));
$macro!((T0, 0), (T1, 1), (T2, 2));
$macro!((T0, 0), (T1, 1), (T2, 2), (T3, 3));
$macro!((T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4));
$macro!((T0, 0), (T1, 1), (T2, 2), (T3, 3), (T4, 4), (T5, 5));
$macro!(
(T0, 0),
(T1, 1),
(T2, 2),
(T3, 3),
(T4, 4),
(T5, 5),
(T6, 6)
);
$macro!(
(T0, 0),
(T1, 1),
(T2, 2),
(T3, 3),
(T4, 4),
(T5, 5),
(T6, 6),
(T7, 7)
);
$macro!(
(T0, 0),
(T1, 1),
(T2, 2),
(T3, 3),
(T4, 4),
(T5, 5),
(T6, 6),
(T7, 7),
(T8, 8)
);
$macro!(
(T0, 0),
(T1, 1),
(T2, 2),
(T3, 3),
(T4, 4),
(T5, 5),
(T6, 6),
(T7, 7),
(T8, 8),
(T9, 9)
);
$macro!(
(T0, 0),
(T1, 1),
(T2, 2),
(T3, 3),
(T4, 4),
(T5, 5),
(T6, 6),
(T7, 7),
(T8, 8),
(T9, 9),
(T10, 10)
);
$macro!(
(T0, 0),
(T1, 1),
(T2, 2),
(T3, 3),
(T4, 4),
(T5, 5),
(T6, 6),
(T7, 7),
(T8, 8),
(T9, 9),
(T10, 10),
(T11, 11)
);
$macro!(
(T0, 0),
(T1, 1),
(T2, 2),
(T3, 3),
(T4, 4),
(T5, 5),
(T6, 6),
(T7, 7),
(T8, 8),
(T9, 9),
(T10, 10),
(T11, 11),
(T12, 12)
);
$macro!(
(T0, 0),
(T1, 1),
(T2, 2),
(T3, 3),
(T4, 4),
(T5, 5),
(T6, 6),
(T7, 7),
(T8, 8),
(T9, 9),
(T10, 10),
(T11, 11),
(T12, 12),
(T13, 13)
);
};
}
macro_rules! impl_project {
( $(($ty:ident, $idx:tt)),+ ) => {
impl< $( $ty: 'static+Clone ),+ > Project for ( $( $ty ),+ ) {
type Projected = ( $( Binding<$ty> ),+ );
fn project(source: &Binding<Self>) -> Self::Projected {
(
$(
{
let source = source.clone();
Binding::mapping(
&source,
|value| value.$idx,
move |binding, value| {
binding.with_mut(|b| {
b.$idx = value;
});
},
)
}
),+
)
}
}
};
() => {};
}
tuples!(impl_project);
impl<T: Project> Binding<T> {
#[must_use]
pub fn project(&self) -> T::Projected {
T::project(self)
}
}