1use ndarray::{IntoDimension, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6};
7use thiserror::Error;
8
9#[derive(Error, Debug)]
12#[error("Expected a {expected}-dimensional array, but got one with {actual} dimensions")]
13pub struct DimensionMismatchError {
14 pub expected: usize,
16
17 pub actual: usize,
19}
20
21pub trait DimFromShapeSlice<T>: Sized {
30 fn from_shape_slice(shape: &[T]) -> Result<Self, DimensionMismatchError>;
36}
37
38macro_rules! impl_dim_from_shape_slice {
39 ($dimtype:ty; $ndim:expr; $($numbers:expr);*) => {
40 impl DimFromShapeSlice<u64> for $dimtype {
41 fn from_shape_slice(shape: &[u64]) -> Result<Self, DimensionMismatchError> {
42 if shape.len() == $ndim {
43 Ok([$(shape[$numbers] as usize),*].into_dimension())
44 } else {
45 Err(DimensionMismatchError { expected: $ndim, actual: shape.len() })
46 }
47 }
48 }
49
50 impl DimFromShapeSlice<usize> for $dimtype {
51 fn from_shape_slice(shape: &[usize]) -> Result<Self, DimensionMismatchError> {
52 if shape.len() == $ndim {
53 Ok([$(shape[$numbers] as usize),*].into_dimension())
54 } else {
55 Err(DimensionMismatchError { expected: $ndim, actual: shape.len() })
56 }
57 }
58 }
59 }
60}
61
62impl_dim_from_shape_slice! { Ix0; 0; }
63impl_dim_from_shape_slice! { Ix1; 1; 0 }
64impl_dim_from_shape_slice! { Ix2; 2; 0;1 }
65impl_dim_from_shape_slice! { Ix3; 3; 0;1;2 }
66impl_dim_from_shape_slice! { Ix4; 4; 0;1;2;3 }
67impl_dim_from_shape_slice! { Ix5; 5; 0;1;2;3;4 }
68impl_dim_from_shape_slice! { Ix6; 6; 0;1;2;3;4;5 }