From 814fbe5667b92b5278a41b42558f06dd4889d591 Mon Sep 17 00:00:00 2001 From: SomeB1oody Date: Sun, 19 Jul 2026 23:46:10 -0700 Subject: [PATCH] feat: add `Dimension::from_slice` Add a public `from_slice` that returns `None` when the slice length does not match the type's dimensionality (`IxDyn` accepts any length). Now `from_dimension` uses `from_slice` --- src/dimension/dimension_trait.rs | 37 +++++++++++++++----------------- tests/dimension.rs | 20 ++++++++++++++++- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/dimension/dimension_trait.rs b/src/dimension/dimension_trait.rs index 373edb35e..b14b53e51 100644 --- a/src/dimension/dimension_trait.rs +++ b/src/dimension/dimension_trait.rs @@ -375,18 +375,24 @@ pub trait Dimension: IxDyn(self.slice()) } + /// Creates a dimension of this type from a slice of axis lengths. + /// + /// Returns `None` if the slice length is incompatible with this + /// dimension type's dimensionality + fn from_slice(ix: &[Ix]) -> Option + { + if Self::NDIM.is_some_and(|n| n != ix.len()) { + return None; + } + let mut s = Self::zeros(ix.len()); + s.slice_mut().copy_from_slice(ix); + Some(s) + } + #[doc(hidden)] fn from_dimension(d: &D2) -> Option { - let mut s = Self::default(); - if s.ndim() == d.ndim() { - for i in 0..d.ndim() { - s[i] = d[i]; - } - Some(s) - } else { - None - } + Self::from_slice(d.slice()) } #[doc(hidden)] @@ -584,15 +590,6 @@ impl Dimension for Dim<[Ix; 1]> { self.remove_axis(axis) } - - fn from_dimension(d: &D2) -> Option - { - if 1 == d.ndim() { - Some(Ix1(d[0])) - } else { - None - } - } private_impl! {} } @@ -1003,9 +1000,9 @@ impl Dimension for IxDyn } } - fn from_dimension(d: &D2) -> Option + fn from_slice(ix: &[Ix]) -> Option { - Some(IxDyn(d.slice())) + Some(IxDyn(ix)) } fn into_dyn(self) -> IxDyn diff --git a/tests/dimension.rs b/tests/dimension.rs index 53f204c6b..76e8fede3 100644 --- a/tests/dimension.rs +++ b/tests/dimension.rs @@ -2,7 +2,7 @@ use defmac::defmac; -use ndarray::{arr2, ArcArray, Array, Axis, Dim, Dimension, IxDyn, RemoveAxis}; +use ndarray::{arr2, ArcArray, Array, Axis, Dim, Dimension, Ix0, Ix2, IxDyn, RemoveAxis}; use std::hash::{Hash, Hasher}; @@ -360,3 +360,21 @@ fn test_all_ndindex() ndindex!(10, 4, 3, 2, 2); ndindex!(10, 4, 3, 2, 2, 2); } + +#[test] +fn from_slice() +{ + assert_eq!(Ix0::from_slice(&[]), Some(Dim([]))); + assert_eq!(Ix0::from_slice(&[1]), None); + + assert_eq!(Ix2::from_slice(&[2, 3]), Some(Dim([2, 3]))); + assert_eq!(Ix2::from_slice(&[2]), None); + assert_eq!(Ix2::from_slice(&[2, 3, 4]), None); + + assert_eq!(IxDyn::from_slice(&[]), Some(IxDyn(&[]))); + assert_eq!(IxDyn::from_slice(&[2, 3, 4, 5]), Some(IxDyn(&[2, 3, 4, 5]))); + + assert_eq!(Ix2::from_dimension(&IxDyn(&[2, 3])), Some(Dim([2, 3]))); + assert_eq!(Ix2::from_dimension(&IxDyn(&[2, 3, 4])), None); + assert_eq!(IxDyn::from_dimension(&Dim([2, 3])), Some(IxDyn(&[2, 3]))); +}