use ndarray::{IntoDimension, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6};
use thiserror::Error;
#[derive(Error, Debug)]
#[error("Expected a {expected}-dimensional array, but got one with {actual} dimensions")]
pub struct DimensionMismatchError {
pub expected: usize,
pub actual: usize,
}
pub trait DimFromShapeSlice<T>: Sized {
fn from_shape_slice(shape: &[T]) -> Result<Self, DimensionMismatchError>;
}
macro_rules! impl_dim_from_shape_slice {
($dimtype:ty; $ndim:expr; $($numbers:expr);*) => {
impl DimFromShapeSlice<u64> for $dimtype {
fn from_shape_slice(shape: &[u64]) -> Result<Self, DimensionMismatchError> {
if shape.len() == $ndim {
Ok([$(shape[$numbers] as usize),*].into_dimension())
} else {
Err(DimensionMismatchError { expected: $ndim, actual: shape.len() })
}
}
}
impl DimFromShapeSlice<usize> for $dimtype {
fn from_shape_slice(shape: &[usize]) -> Result<Self, DimensionMismatchError> {
if shape.len() == $ndim {
Ok([$(shape[$numbers] as usize),*].into_dimension())
} else {
Err(DimensionMismatchError { expected: $ndim, actual: shape.len() })
}
}
}
}
}
impl_dim_from_shape_slice! { Ix0; 0; }
impl_dim_from_shape_slice! { Ix1; 1; 0 }
impl_dim_from_shape_slice! { Ix2; 2; 0;1 }
impl_dim_from_shape_slice! { Ix3; 3; 0;1;2 }
impl_dim_from_shape_slice! { Ix4; 4; 0;1;2;3 }
impl_dim_from_shape_slice! { Ix5; 5; 0;1;2;3;4 }
impl_dim_from_shape_slice! { Ix6; 6; 0;1;2;3;4;5 }