use validatrix::Accumulator;
pub trait NDim {
fn ndim(&self) -> usize;
}
pub trait MaybeNDim {
fn maybe_ndim(&self) -> Option<usize>;
fn ndim_conflicts<T: MaybeNDim>(&self, other: &T) -> Option<(usize, usize)> {
if let (Some(d1), Some(d2)) = (self.maybe_ndim(), other.maybe_ndim()) {
if d1 != d2 {
return Some((d1, d2));
}
}
None
}
}
impl<T: NDim> MaybeNDim for T {
fn maybe_ndim(&self) -> Option<usize> {
Some(NDim::ndim(self))
}
}
pub(crate) fn validate_ndims<'a, T: MaybeNDim + 'a>(
accum: &mut Accumulator,
expected: Option<usize>,
dimensionals: impl IntoIterator<Item = &'a T> + 'a,
) {
let mut it = dimensionals
.into_iter()
.enumerate()
.filter_map(|(idx, d)| d.maybe_ndim().map(|n| (idx, n)));
let exp = match expected {
Some(e) => e,
None => {
if let Some((_idx, n)) = it.next() {
n
} else {
return;
}
}
};
for (idx, n) in it {
if n != exp {
accum.add_failure_at(
idx,
format!("inconsistent dimensionality: got {n}D, expected {exp}D"),
);
}
}
}