use crate::{
hlist,
hlist::Get,
};
pub trait Reshape<Target, Indices, Null> {
fn reshape(self) -> Target;
}
impl<Null> Reshape<Null, hlist::Null, Null> for Null {
fn reshape(self) -> Null {
self
}
}
impl<List, TargetHead, TargetTail, Index, Indices, Null>
Reshape<(TargetHead, TargetTail), (Index, Indices), Null> for List
where
List: Get<TargetHead, Index>,
List::Remainder: Reshape<TargetTail, Indices, Null>,
{
fn reshape(self) -> (TargetHead, TargetTail) {
let (target, remainder) = self.get();
(target, remainder.reshape())
}
}
#[cfg(test)]
mod tests {
use super::Reshape;
#[derive(Debug, PartialEq)]
struct A;
#[derive(Debug, PartialEq)]
struct B;
#[derive(Debug, PartialEq)]
struct C;
#[derive(Debug, PartialEq)]
struct D;
#[derive(Debug, PartialEq)]
struct E;
#[derive(Debug, PartialEq)]
struct Null;
#[test]
fn reshape_empty() {
assert_eq!(Reshape::<Null, _, Null>::reshape(Null), Null);
}
#[test]
fn reshape_single() {
assert_eq!(Reshape::<(A, Null), _, Null>::reshape((A, Null)), (A, Null));
}
#[test]
fn reshape_multiple_same_order() {
assert_eq!(
Reshape::<(A, (B, Null)), _, Null>::reshape((A, (B, Null))),
(A, (B, Null))
);
}
#[test]
fn reshape_multiple_different_order() {
assert_eq!(
Reshape::<(B, (A, Null)), _, Null>::reshape((A, (B, Null))),
(B, (A, Null))
);
}
#[test]
fn reshape_long() {
assert_eq!(
Reshape::<(B, (D, (E, (A, (C, Null))))), _, Null>::reshape((
A,
(B, (C, (D, (E, Null))))
)),
(B, (D, (E, (A, (C, Null)))))
);
}
}